模块加载
一.CommonJS模块
CommonJS模块只有在运行时候才能确定输入输出变量,这种加载称为“运行时加载”。
let { stat, exists } = require('fs');
等价于
let fs=require('fs');
let stat=fs.stat;
let exists=fs.stat;
本质上是先整体引入fs模块,在生成一个对象fs后重新读取属性值,
二.ES6模块
1.ES6模块为“编译时加载”(也叫静态加载)即ES6可以在编译时候完成模块加载,效率要高于CommonJS模块。
2.ES6模块自动采用严格模式(顶层this指向undefined)
import { stat, exists } from ('fs');
三.export导出
1.直接输出变量
export var v1 = 'Michael';
export function foo(x, y) {
return x * y;
};
2.使用{}导出一组变量
var v1 = 'Michael';
function foo(x, y) {
return x * y;
};
export { v1,foo };
as重命名
export输出的变量就是本来的名字,但是可以使用as关键字重命名。
function v1() {}
let arr = [1, 23]
function foo(x, y) {
return x * y;
};
export {
arr as streamV1,
arr as streamV2,
v1 as v2,
foo
}
四.import
1.引入
import { arr, v1} from './profile.js';
2.as重命名
使用as关键字,将输入的变量重命名
import { temArr as arr } from './profile.js';
3.限制
import命令输入的变量都是只读的,因为它的本质是输入接口。不允许在加载模块的脚本里面,改写接口。
import {arr} from './profile.js'
arr= {}; // Syntax Error : 'a' is read-only;
允许修改属性
import {arr} from './profile.js'
arr.shift() // 合法操作
4.模块的整体加载
用星号(*)指定一个对象,所有SW输出值都加载在这个对象上面。
import * as object from './xxx.js'
//此时object上存在foo、arr、v1属性
由于模块整体加载在object上,所以不允许运行时候,改变(增、删属性)及:
object.foo=“hello”;//修改报错
object.a=“hello”;//增加报错
五.模块动态加载
1.import(路径)实现动态加载
function v1() { }
let arr = [1, 23]
export {
v1,
arr
};
import()返回一个Promise对象
//1
import('./moudle.js').then((object)=>{
console.log(object)
})
// 2
import('./moudle.js').then(({v1,arr})=>{
console.log(v1,arr)
})
2.动态模块路径
// fn返回模块路径
import(fn()).then((object)=>{
console.log(object)
})
CommonJS模块与EL6模块区别:
CommonJS模块的加载机制是,输入的是被输出的值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。 即如果上述引用改变fs.stat属性值,对于CommonJS模块并不会改变初始值。
ES Module中是不一样的,它是静态加载。也就是在代码静态解析阶段就已经确认好模块依赖关系了。即如果上述引用改变fs.stat属性值,原模块值也会改变。
C
o
m
m
o
n
J
S
模块输出的是一个值的拷贝,
E
S
6
模块输出的是值的引用。
CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
CommonJS模块输出的是一个值的拷贝,ES6模块输出的是值的引用。
参考链接:
CommonJS规范 – JavaScript 标准参考教程(alpha) (ruanyifeng.com)