ES6模块加载的机制,与CommonJS模块完全不同。CommonJS模块输出的是一个值的拷贝,而ES6模块输出的是值的引用。CommonJS模块输出的是被输出值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
<span style="font-size:18px;">//输入Tab.js
let count = 1;
function compute(){
count++;
}
module.exports = {
count:count,
compute:compute
};
//输出TabMain.js
let TabES5 = require('./Tab');
console.log(TabES5.count);//1
TabES5.compute();
上面代码说明,Tab.js模块加载以后,它的内部变化就影响不到输出的TabES5.count了。这是因为TabES5.count是一个原始类型的值,会被缓存。除非写成一个函数,才能得到内部变动后的值。
<span style="font-size:18px;">let count = 1;
function compute(){
count++;
}
module.exports = {
get count() {
return count
},
compute:compute
};</span>
ES6模块的运行机制与CommonJS不一样,它遇到模块加载命令import时,不会去执行模块,而是只生成一个动态的只读引用。等到真的需要用到时,再到模块里面去取值。因此,ES6模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。
<span style="font-size:18px;">//输入Tab.js
let count = 1;
function compute(){
count++;
}
export {count,compute}
//输出TabMain.js
import {count,compute} from './Tab';
console.log(count);//1
compute();
console.log(count);//2</span>
由于ES6输入的模块变量,只生成一个动态的只读引用,所以这个变量是只读的,对它进行重新赋值会报错,只能改变对象属性的值,不能够改变引用。如果是一个基本数据类型,不是引用类型的数据,也不能改变他的值。
<span style="font-size:18px;">//输入Tab.js
export let obj = {};
//输出TabMain.js
import {obj} from './Tab';
obj.len = 10;
console.log(obj);
//obj = {len:20};SyntaxError: "obj" is read-only
说明:如果在Tab.js中obj是10,在TabMain.js中也不能改变obj=20。</span>