@JunQiu
2018-09-18T11:22:16.000000Z
字数 2018
阅读 3572
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.jsvar b = require('./b');console.log(b.foo);setTimeout(() => {console.log(b.foo);console.log(require('./b').foo);}, 1000);// b.jslet 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时,不会去执行模块,而是只生成一个引用。等到真的需要用到时,再到模块里面去取值。
