目的:将大程序拆分成互相依赖的小模块文件.CommonJS 和 AMD 两种,前者用于服务器,后者用于浏览器.他俩都是运行时才确定
:ES6 模块的设计思想(浏览器和服务器通用)是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量
ES6 模块不是对象,而是通过export
命令显式指定输出的代码,再通过import
命令输入
// CommonJS模块
let { stat, exists, readFile } = require('fs'); // 等同于
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;
////整体加载fs模块(即加载fs的所有方法),生成一个对象(_fs),然后再从这个对象上面读取 3 个方法。这种加载称为“运行时加载”,因为只有运行时才能得到这个对象,导致完全没办法在编译时做“静态优化” // ES6模块
import { stat, exists, readFile } from 'fs';
//实质是从fs模块加载 3 个方法,其他方法不加载。这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载,这也导致了没法引用 ES6 模块本身,因为它不是对象
模块功能的两个命令:
1export
命令用于规定模块的对外(导出功能)接口,
2import
命令用于导入其他模块提供的功能
export命令:
1:输出变量或者函数,class等
let name= "panrui"
function test() {
console.log(name)
}
export{name,test}
//通过as使用别名
export{name as ne,test as tt}
2:对外的接口必须和模块内部建立一一对应的关系...待续
3:对外的接口与其对应的值是动态绑定,当对应的值改变的时候,通过接口是可以实时获取的
let firstName = "Michael"
function test() {
firstName = "panrui"
}
export{firstName,test} import{firstName,test} from "./profile.js"
firstName //Michael
test();
firstName //panrui
4export命令可以出现在模块顶层的任何位置
import命令:
1:import命令接受一对大括号,里面指定要从其他模块导出的变量名,必须和被导入模块的对外接口的名称相同
2:同理也可以采用as对导入的变量名进行重命名
3:导入的变量都是只读的,千万千万千万不要去修改接口.
4:import命令具有提升的效果,会提升到整个模块的头部,最先执行 (因为她是在预编译的时候执行的,在代码执行之前)
5:整体加载,通过*制定一个对象,所有的输出值都加载到这个对象上面,
export default命令:(本质上是输入一个叫做default的变量或者函数)
注意:关注他与export在导出方面的区别,import在导入方面也有些许的差异
1:为模块指定一个默认的输出,其他模块加载该模块的时候就可以指定一个任意名字加载这个默认输出
2:导入一个模块的默认输出,导入的时候不需要放在大括号里面
export与import的混合写法:如果在一个模块中,导入和导出同一个模块
export { foo, bar } from 'my_module'; // 可以简单理解为
import { foo, bar } from 'my_module';
export { foo, bar };
//但需要注意的是,写成一行以后,foo和bar实际上并没有被导入当前模块,只是相当于对外转发了这两个接口,导致当前模块不能直接使用foo和bar
模块的继承: 继承的意思是模块的本身的导出加上父类的导出,所以模块本身还是不能使用,只是起到转发作用
// circleplus.js export * from 'circle';
export var e = 2.71828182846;
export default function(x) {
return Math.exp(x);
}
//circleplus模块先导入circle,在导出circle,相当于继承.
//同时又导出自己的默认方法和其他变量
跨模块常量:待续....