commonJS 模块
commonJS的模块规范在Node中发扬光大,总的来说,它的特性有这几个:
1.动态加载模块
commonJS和es6的最大区别大概就在于此了吧,commonJS模块的动态加载能够很轻松的实现懒加载,优化用户体验。
2.加载整个模块
commonJS模块中,导出的是整个模块。
3.每个模块皆为对象
commonJS模块都被视作一个对象。
4.值拷贝
commonJS的模块输出和 函数的值传递相似,都是值的拷贝
B文件
//calculator.js
module.exports={name:"calculator"};
A文件
//index.js
const name=require('./calculator.js').name;
当模块A加载模块B时,会执行B中的代码,并将其module.exports对象作为require函数的返回值进行返回。并且require的模块路径可以动态指定,并支持传入一个表达式或者一个if进行判断是否加载模块。因此可以看出,在commonJS模块被执行前,并没有办法确定明确的依赖关系,模块的导入、导出发生在代码的运行阶段。
es6 模块
1.静态解析
即在解析阶段就确定输出的模块,所以es6模块的import一般写在被引入文件的开头。
2.模块不是对象
在es6里,每个模块并不会当做一个对象看待
3.加载的不是整个模块
在es6模块中经常会看见一个模块中有好几个export 导出
4.模块的引用
es6模块中,导出的并不是模块的值拷贝,而是这个模块的引用
//calculator.js
export const name='calculator';
//index.js
import {name} from './calculator.js';
ES6 Module的导入、导出语句都是声明式的,它不支持导入的路径是一个表达式,并且导入、导出语句必须位于模块的顶层作用域不能放到if语句中。因此ES6 Module是一个静态模块结构。
ES6 Module相比与CommonJS的优点
① 死代码检测和排除。我们可以用静态分析工具检测出哪些模块没有被调用过。
② 模块变量类型检查。
③ 编译器优化。ES6 Module支持直接导入变量,减少了引用层级,程序效率更高
值拷贝与动态映射
在导入一个模块的时候,对于CommonJS来说获取的是一份导出值的拷贝;而ES6 Module则是值的动态映射,并且这个映射是可读的。
CommonJS值拷贝例子
//calculator.js
var count=0;
module.exports={
count:count,
ADD:function (a,b) {
count+=1;
return a+b;
}
};
//inde.js
var count=require('./calculator').count;
var add=require('./calculator').ADD;
console.log(count);
add(2,3);
console.log(count);
count +=1;
console.log(count);
运行结果
index.js中的count是对calculator.js中的count的一份拷贝,因此在调用ADD函数的时候,虽然改变了calculator.js中的count的值,但是并不会对index.js中导入时创建的副本造成影响。也就是说你在index.js中只要不是通过ADD函数对count的操作,都不会影响到calculator.js中的count。而是影响了副本的count
ES6 Module动态映射例子
//calculator.js
var count=0;
const ADD=function(a,b){
count+=1;
return a+b;
};
export {count,ADD}
//inde.html
<script type="module">
import {count,ADD} from './src/calculator.js';
console.log(count);
ADD(2,3);
console.log(count);
</script>
运行结果
可以发现导入的变量其实是对原有值的动态映射。index.html中的count是对calculator.js中count值的实时反映,当我们调用ADD函数更改了calculator.js中count值时,index.html中的count的值也会随之变化。
https://blog.csdn.net/haodawang/article/details/77199980
https://blog.csdn.net/qq_42683219/article/details/103939237