@JunQiu
2018-09-18T19:22:16.000000Z
字数 2018
阅读 3132
summary_2018/07
tools
language_js
designIdea
// iterm 终端分屏
ctrl+D(+shift)
// 方向键切换到指定位置的分屏
⌘ + opt +
// 遇到一些小问题
vim insert 不能使用,可以使用i代替
// 在控制台打开本地目录 open .
## ES6模块机制与CommonJS、AMD的差异
主要有以下两个差异:
1、ES6 模块输出的是值的引用,输出接口动态绑定,而 CommonJS 输出的是值的拷贝
2、ES6 模块编译时执行,而CommonJS模块总是在运行时加载
具体来理解(以CommonJS为例):
### 不同点
1、CommonJS输出的是值的拷贝:
// a.js
var b = require('./b');
console.log(b.foo);
setTimeout(() => {
console.log(b.foo);
console.log(require('./b').foo);
}, 1000);
// b.js
let foo = 1;
setTimeout(() => {
foo = 2;
}, 500);
module.exports = {
foo: foo,
};
// 执行:node a.js,执行结果:
// 1
// 1
// 1
## 如果想要在CommonJS中动态获取模块中的值,那么就需要借助于函数延时执行的特性
## 可以看出:
// CommonJS 模块中require引入模块的位置不同会对输出结果产生影响,并且会生成值的拷贝(以拷贝时运行的值为准,一旦拷贝不会发生改变)
// CommonJS 模块重复引入的模块并不会重复执行,使用第一次拷贝的值
2、ES6 输出值的引用
ES6 模块中就不再是生成输出对象的拷贝,而是模块值的引用。
3、ES6 静态编译,CommonJS 运行时加载
ES6 模块编译时执行会导致有以下两个特点:
-> import 命令会被JavaScript引擎静态分析,优先于模块内的其他内容执行。
-> export 命令会有变量声明提前的效果。
4、import命令会被 JavaScript 引擎静态分析
// 报错,不能用于任何表达式
if (x === 2) {
import MyModual from './myModual';
}
而require是运行时加载模块,import命令无法取代require的动态加载功能。有一个提案,建议引入import()函数,完成动态加载,import()返回一个 Promise 对象.
### 相同点
1、当你重复引入某个相同的模块时,模块只会执行一次
## CommonJS的做法是,一旦出现某个模块被"循环加载",就只输出已经执行的部分,还未执行的部分不会输出。
Tips:require命令第一次加载该脚本,就会执行整个脚本,然后在内存生成一个对象。
{
id: '...',
exports: { ... },
loaded: true,
...
}
以后需要用到这个模块的时候,就会到exports属性上面取值。即使再次执行require命令,也不会再次执行该模块,而是到缓存之中取值(原始数据类型会被缓存),但是也可以通过闭包函数保持对模块内部的原始数据类型的引用。
## ES6模块的运行机制与CommonJS不一样,它遇到模块加载命令import时,不会去执行模块,而是只生成一个引用。等到真的需要用到时,再到模块里面去取值。