本文同步自我得博客:http://www.joeray61.com

简介

在当今的Javascript程序中,模块的作用不言而喻,目前广泛应用的主要有AMD(浏览器端)和CommonJS(服务器端)。但是Javascript一直没有在语言层面支持模块,直到ES6的出现。相信在不久的将来,ES6的模块一定会全面取代AMDCommonJS

export

ES6的模块提供了2个新的语法,分别是exportimportexport就是模块用来对外暴露数据的接口,具体用法如下。

export let a = 1;
export class A {};
export let b = () => {};

输出多个数据时不必分别export,可以用一个export统一输出

let a = 1;
class A {};
let b = () => {};
export {a, A, b};

import

export对应,import就是ES6的模块用来引入数据的命令。

我们先来建立一个数据数据的文件a.js:

// a.js
let a = 1;
export {a};

然后再创建一个b.js用来导入a.js暴露的数据

// b.js
import {a} from './a';
console.log(a);    // 1

如果要导入的模块暴露了很多变量,而你又不想一个一个地去写要import的数据时,可以使用*

// b.js
import * as obj from './a';
console.log(obj.a);    // 1

需要注意的是,import使用的变量名必须跟export使用的变量名一致

rename

importexport的时候都是可以对变量进行重命名的

// a.js,用于export变量a,但是导出时将a改名为aa
let a = 1;
export {a as aa};
// b.js用于import从a.js导出的数据aa,但是在导入时将aa改名为b
import {aa as b} from './a';
console.log(a);   // undefined
console.log(aa);  // undefined
console.log(b);   // 1

default

export时可以指定要默认导出的数据

// a.js
let a = 1;
let aa = 2;
export default a;
export {aa};
// 也可以写成
export {a as default, aa};

导入默认数据时需要这样写:

// b.js
import x from './a';
console.log(x);  // 1

细心的同学可能发现了,这里import的时候使用的变量名是x,这就是default的特权了,导入时使用的变量名可以随便取,不需要跟导出时的变量名一致。

另外,如果同时要导入default和其他数据时该怎么写呢?

// b.js
import x, {aa} from './a';
console.log(x);    // 1
console.log(aa);   // 2

ES6模块加载实质

CommonJS加载模块时,加载的是值的副本,而ES6的模块加载,加载的是值的引用。还是直接上代码吧

// lib.js
export let x = 1;
export let changeX = () => {
    x++;
};
// a.js
import {x, changeX} from './lib';
changeX();
console.log(x);
// b.js
import {x, changeX} from './lib';
changeX();
console.log(x);
// index.js
import './a';
import './b';

执行index.js输出的值是23,这就说明a.jsb.js执行的时候改变的都是lib.js里的x,而不是各自操作了一份副本

注意点

  1. ES6的模块采用严格模式,无论你是否申明use strict;

  2. import具有提升效果,即使写在文件的后面,也会被提到头部首先执行

本文为学习过程中整理,如有问题欢迎交流~


JoeRay61
2.3k 声望182 粉丝