2026-10-22 00:26:08
语法不同:
CommonJS:使用require导入模块,使用module.exports导出模块。
ES Module (ESM):使用import导入模块,使用export导出模块。
加载时机不同:
CommonJS:是运行时加载模块,即在代码执行到require语句时才会加载模块。
ESM:是静态编译期间就会确定依赖,即在编译时就会解析所有的import语句,并将所有依赖提升到顶部。
模块提升:
CommonJS:不会提升require语句,即require语句会在执行到该语句时才会执行。
ESM:会在编译时将所有import语句提升到顶部。
值的拷贝与引用:
CommonJS:导出的是一个值的拷贝,导出之后修改模块内部的值不会影响引用的地方,引用的地方修改也不会影响原模块。
ESM:由于是静态解析,其导入导出机制与CommonJS有所不同,但同样遵循值的拷贝原则(对于基本数据类型),不过由于ESM的静态特性,其模块解析和加载过程更为明确。
Loader:
作用:用于对模块源码的转换。Loader描述了Webpack如何处理非JavaScript模块,并且在构建过程中引入这些依赖。
功能:Loader可以将文件从不同的语言转换为JavaScript,例如将TypeScript转换为JavaScript,或将CSS文件转换为JavaScript模块。
理解:Loader可以理解为Webpack的横向广度,借助Loader,Webpack可以打包处理各种扩展语言。
Plugin:
作用:目的在于解决Loader无法实现的其他事,比如对代码的打包优化和压缩,到重新定义环境变量等。
功能:插件可以用来处理各种各样的任务,如代码分割、性能优化、资源管理等。
理解:Plugin可以理解为Webpack的纵向深度,在Webpack的生命周期内注入不同的插件来扩展更多的能力。
基本数据类型(String、Number、Boolean、Null、undefined、Symbol):
存储位置:栈内存中。
原因:基本数据类型占用空间较小、大小固定,按值访问,属于频繁使用的数据。
注意:闭包中的基本数据类型的变量不是在栈内存中,而是在堆内存中。
引用数据类型(对象、数组、方法等):
存储位置:堆内存中。
原因:引用数据类型大小不确定,经常需要占用很大的空间。
访问方式:引用数据类型会在栈内存中存储指针,指向堆中实体的起始地址。寻找引用值时,会首先检索它在栈中的地址,然后取得地址之后从堆中获取到实体。
JavaScript执行阻塞渲染:
原因:在JavaScript加载之前,浏览器不知道JavaScript要干什么。如果在渲染DOM时脚本中有对DOM节点进行操作的话,会出现不可预期的结果,导致渲染混乱。
机制:因此设置GUI渲染和JavaScript线程互斥,避免这种情况发生。
CSS不阻塞DOM解析:
原因:DOM解析和CSS解析是两个并行的线程。
渲染依赖:虽然CSS的加载不会阻塞DOM的解析,但是Render Tree是依赖DOM Tree和CSSOM Tree的。因此,CSS的加载会阻塞DOM的渲染,直到CSSOM构建完成。
原因:
JavaScript中Number类型使用的是IEEE 754规范中的64位双精度浮点数编码。小数和整数都是被当做浮点数进行存储的。
在做运算时,会将用科学计数法表示的二进制的小数进行计算,二进制计算结束之后再转成十进制,导致出现了精度问题。
常见解决策略:
将小数转为字符串处理。
乘以一个基数计算完之后再除回去(例如,将小数放大到整数进行计算,然后再缩小回去)。