# 模块化

详情参阅我的CSDN阮一峰-Module

# 常用写法

exportfile.js:

//导出变量
export var firstName = "wang";
export var lastName = "long kai";

//导出函数
export function sayHello(name){
	console.log(`hello ${name}`);
}

//导出对象
var address = "beijing";
var age = 24;
var sayAddress = function(address){
    console.log(`address ${address}`);
}
export {address,age,sayAddress};

//默认导出(一个模块只能有一个默认导出)
export default 42;

importfile.js:

//import 默认导出,{非默认导出...} from 'someWhere.js'
import deafultNum,{firstName,lastName,sayHello,address,age,sayAddress} from './exportfile.js' //可用解构赋值

# export的注意点

1. export语句输出的接口与其对应的值是动态绑定关系,即通过该接口获取到的是模块内部实时的值

export var foo = "bar";
setTimeout(()=>foo="wlk",500);

上面代码输出的接口(变量)是foo,值为bar。但是,500ms之后值变为wlk。引入该接口的模块中的值也会相应改变。

2. export语句可以出现在模块的任何位置,前提是处于模块的顶层作用域

function foo(){
    export var wlk = "bar";
}

上面的代码会报错,export只能在模块的顶层作用域,而此处位于函数作用域中。


# import的注意点

1. 从其他模块导入的变量是只读的,不能进行修改

//lib.js
export let obj = {name:"wlk"};

//main.js
import {obj} from "lib.js";
obj.age = 22;//可以
obj.name = "hq";//不可以

上面代码中,main.js从lib.js输入对象obj,可以对obj添加属性,但是不能重新赋值。

2. import命令具有提升效果,会提升到整个模块的头部并首先执行。

foo();
import {foo} from "test.js";

上面代码不会出错,因为import的执行早于foo的调用。这种行为的本质是,import命令是编译阶段执行的,在代码执行之前。

3. 如果多次使用同一import语句,那么只会执行一次,而不会执行多次。

import {foo} from "test.js";
import {foo} from "test.js";

其实只相当于执行语句一次。

# 其他模块化方案

  • CommonJS规范

    CommonJS规范用于服务器端,nodejs就是使用的Commonjs规范。一个js文件就是一个js模块,模块只有一个出口,即module.exports 对象,我们需要把模块希望输出的内容放入该对象。通过require方法,加载一个模块,是运行时加载。而ES6的模块化方案是静态加载。

  • AMD和CMD规范

    AMD和CMD规范适用于浏览器端。require.js就是AMD规范,sea.js就是CMD规范。
    两者的区别是
    AMD推崇依赖前置,在定义模块时就引入其依赖的模块。
    CMD推崇就近依赖,只用在用到某个模块的时候再去require。
    二者的执行机制也不一样:二者都是异步加载模块的。
    AMD是加载完模块后立即执行模块,所有模块加载和执行完毕后就进入require的回调函数,执行主逻辑。
    CMD是加载完某个依赖后并不执行,在所有依赖模块加载完毕后,进入主逻辑,遇到require语句的时候,就执行相应的模块。

作者:王龙楷; 标签:原创; 提交时间: 11/29/2020, 4:40:26 PM