- ES6之前模块加载方案,CommonJS (用于服务器)和 AMD(浏览器)
2.CommonJS 和 AMD模块只能在运行时确定模块的依赖关系
3.es6模块不是对象,而是通过export命令显示指定输出代码,再通过import命令:
import { stat, exists, readFile} form 'fs'
上面代码的实质是从fs模块加载3个方法,其他方法不加载。这种加载称为’编译时加载'或者静态加载,即ES6可以在编译时就完成模块加载,同时也导致了没法引用ES6模块本身,因为它不是对象。
4.es6模块自动采用严格模式
变量必须声明后再使用
-函数的参数不能有同名属性,否则报错
-不能使用with语句
-不能对只读属性赋值,否则报错
-不能使用前缀 0 表示八进制数,否则报错
-不能删除不可删除的属性,否则报错
-不能删除变量delete prop,会报错,只能删除属性delete global[prop]
-eval不会在它的外层作用域引入变量
-eval和arguments不能被重新赋值
-arguments不会自动反映函数参数的变化
-不能使用arguments.callee
不能使用arguments.caller
-禁止this指向全局对象
-不能使用fn.caller和fn.arguments获取函数调用的堆栈
-增加了保留字(比如protected、static和interface)
es6模块之中,顶层的this指向undefined,即不应该在顶层代码使用this
5.一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果希望外部能够读取模块内部某个变量,必须使用export关键字输出该变量。
var firstName = 'Michael'; var lastName = 'Jackson'; var year = 1958; export {firstName, lastName, year};
以上代码对外输出了3个变量
export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。(重点1是接口)
// 报错
export 1;
// 报错
var m = 1;
export m;
上面两种写法都会报错,因为没有提供对外的接口。第一种写法直接输出 1,第二种写法通过变量m,还是直接输出 1。1只是一个值,不是接口。正确的写法是下面这样。
// 写法一
export var m = 1;
// 写法二
var m = 1;
export {m};
// 写法三
var n = 1;
export {n as m};
export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。(重点2:值是实时的)
export var foo = 'bar';
setTimeout(() => foo = 'baz', 500);
上面代码输出变量foo,值为bar,500 毫秒之后变成baz。
这一点与 CommonJS 规范完全不同。CommonJS 模块输出的是值的缓存,不存在动态更新。
最后,export命令可以出现在模块的任何位置,只要处于模块顶层就可以。
import {firstName, lastName, year} from './profile.js';
上面代码的import命令,用于加载profile.js文件,并从中输入变量。import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(profile.js)对外接口的名称相同。
(重点1)
import命令输入的变量都是只读的,因为它的本质是输入接口。(重点2)
import后面的from指定模块文件的位置,可以是相对路径,也可以是绝对路径,.js后缀可以省略。如果只是模块名,不带有路径,那么必须有配置文件,告诉 JavaScript 引擎该模块的位置。(重点3)
import命令具有提升效果,会提升到整个模块的头部,首先执行。(重点4)
import语句会执行所加载的模块,但是不输入任何值,如果多次重复执行同一句import语句,那么只执行一次。(重点5)
import { foo } from 'my_module';
import { bar } from 'my_module';
===
import { foo, bar } from 'my_module';
import语句是 Singleton 模式。
- export default 命令
e.g1:
export default function () {
console.log('foo');
}
上面代码是一个模块文件export-default.js,它的默认输出是一个函数。
其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。
import customName from './export-default';
customName();
e.g2:
export default function foo() {
console.log('foo');
}
// 或者写成
function foo() {
console.log('foo');
}
export default foo;