找遍度娘,发现好多文章都是拿来主义,阮一峰老师ECMAScript6入门的文档各类花式开枝散叶,语法上阮一峰老师讲的已经很是细致了,可是概念上的东西我仍是有点模糊。es6
文档里讲了ES6模块加载和CommonJS的区别(ES5的模块引用表现形式可能有些不一样,但本质其实都是把模块做为对象引用,因此这个区别也是ES6和ES5模块引用的区别):bash
1.CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用ui
2.CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。google
我这人比较懒,不太习惯单纯的copy,强烈推荐你们先看一下阮一峰老师的ECMAScript 6 入门spa
文档里针对这两点作了详细的解释,针对第一点解释说ES6 模块不是对象,那我就想知道不是对象他究竟是什么,百度了很久,终于在google搜索的第一篇的文章里找到了答案:3d
每个 ES6 模块都是一个包含 JS 代码的文件,模块本质上就是一段脚本,而不是用module关键字定义一个模块。其实我想知道的就是这句话, ES6 模块是脚本。code
根据上面获得的概念,不难理解CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。 CommonJS的模块本质是一个对象的引用,所以须要运行时加载。而ES6的module其实就是引入了一个新的概念,模块不是对象而是脚本,这样就能够在编译的时候加载。cdn
至于CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。这个点咱们能够想象一下import和export到底作了什么,它们在程序加载的时候组成一对不一样于"="的对应关系。对象
举个例子
case1 CommonJS模块引用blog
//a.js
let func=require('./b').func,
a=require('./b').b;
a=1;
func();//输出2
//b.js
let b=2;
function func() {
console.log(b);
}
module.exports = {
func: func,
b: b
};
复制代码
case2 ES6模块引用
//a.mjs
import {b as a} from "./b.mjs"
import {func} from "./b.mjs"
a=1;//报错
func();
//b.mjs
export function func() {
console.log(b)
}
export let b=2;
复制代码
再来一张在下的大做
正常状况下,咱们把一个存放值的变量b赋值给变量a,其实就是把b里面存放的值放进a的存储空间中,这一点没什么异议。而case1这种状况,CommonJS 模块是一个正常的JS对象,a=require('./b').b
等同于a=b
因此遵循JS的变量赋值的规则。
ES6 模块输出的是值的引用。在ES6中,case3这种状况下,若是咱们试图直接修改a的值会报错,由于a不是b,a是指向变量b的变量,若是要修改a的值,只有在被引用的模块里修改b的值,a的值才会发生改变。因此咱们能够认为export和import带来的关系是,a的存储空间指向变量b,而且这个关系不能够被破坏。
[深刻浅出 ES6(十六):模块 Modules]www.infoq.cn/article/es6… ECMAScript 6 入门