原文:http://es6.ruanyifeng.com/#docs/module
ES6模块是静态加载的(编译时加载),在编译时就可以确定模块的输入输出和模块间的依赖关系。
ES6模块自动采用严格模式
一个模块就是一个独立的文件。文件内部的所有变量外部无法访问。如果希望允许外部访问模块内部某个变量,需要使用export
命令输出该变量。
#1. export
命令
export
命令用于规定模块的对外接口(暴露哪些变量)
#1.1 输出变量、函数和类
//frank.js 写法一
export var name = 'FrankZ';
export var age = 25;
export function work(x, y) {return x + y};
//frank.js 写法二
var name = 'FrankZ';
var age = 25;
function work(x, y) {return x + y};
export {name,age, work};
这两种写法是等价的,建议使用后者,输出了哪些变量清晰明了。
注意:export {name,age, work};
,不要把{name,age, work}
当成对象,这只是ES6规定的暴露接口的语法形式。
#1.2 重命名
var a = {x: 1};
var b = {x: 2};
export {
a as c,
b as d,
b as e
};
通常export输出的变量就是本来的名字,但可以使用as
关键字重命名。只有export {...}这种形式才可以重命名
上面代码重命名了对外接口a、b,这样a,b,c,d都被暴露出去了。引用时,a和c、b和d都指向同一个对象
其中b被重命名了两次。
#1.3 export命令规定的是对外接口,必须与模块内部变量一一对应
//错误写法
export 1; //报错,1只是一个值,没有提供对外接口(外部不晓得用哪个变量名来访问1)
var m = 1;
export m; //报错,同上
//正确写法
var m = 1;
export {m} // 正确写法,规定了对外接口m;{m}不是对象
export var m = 1; // 正确写法,应该算是上面写法的简写吧
#1.4 TIPS
- export命令输出的接口与其对应的值是动态绑定关系,通过接口可以取到模块内部实时的值
- export命令可以出现在模块任何位置(但必须是顶层,即不能处于块级作用域中)
#2. import
命令
import
命令用于加载模块,导入模块输出的变量。
#2.1 import
命令接受一对大括号,from
指定模块文件的位置
import {name, age, work} from './frank'
#2.2 import
命令可以使用as
关键字重命名导入的变量
import {name as uid} from './frank'
不同于export
命令,这里如果访问name将会报错 【ReferenceError: name is undefined】
#2.3 import
命令会执行所加载的模块,因此也可以选择不导入接口
import 'lodash'
#2.4 整体加载
import * as frank from './frank';
上面代码使用星号(*)指定了一个对象frank,所有输出值都挂在这个对象上面。
需要注意的是挂载到frank的各项属性仍然是只读的。
#2.5 Tips
- 大括号里面指定要导入的变量名(必须与被导入模块对外接口的名称相同)
- 文件位置可以是相对路径也可以是绝对路径,
.js
后缀可以省略。如果只是模块名不带路径,那么必须有配置文件 -
import
命令具有提升效果,会提升到某块头部首先执行 -
import
是静态执行,所以不能使用表达式和变量 - 如果多次重复执行同一句
import
语句,那么只会执行一次;多次加载同一个模块只会得到同一个模块实例(单例模式)
import 'lodash';
import 'lodash';
import 'lodash'; // 只会执行一次
import {name} from './frank'
import {age} from './frank'
//等同于
import {name, age} from './frank'
#3 MORE
#3.1 export default
命令
var g = 1
export default g
//
export default g = 1
//
export default function(){} // 导出匿名函数,import引入后function name属性为default
//
export default function test(){} // 导出匿名函数,import引入后function name属性为test
import anything from './frank' // 只有当目标模块有default输出时才可以这样引入; 如果只有默认输出,import不能加大括号
本质上export default
命令就是输出一个叫做default
的变量或方法,然后允许在引用的时候指定任意名字
//
export default var g = 1 // 错误, 原因如上所述
//
export default a
//等同于
export {a as default}
export default 100 // 正确
Tips
-
export default
命令用于指定模块的默认输出,那么很显然一个模块只能有一个默认输出。 - 如果想在一条import语句中同时导入默认接口和其他接口,可以写成下面这样:
import def, {a, b, c} from './frank'
#3.2 export & import 复合写法
当一个模块需要导入并导出同一个模块,import和export语句可以写在一起
export {a, b} from './frank'
// 写成一行后,a, b 实际上并没有被导入当前模块,不能直接使用a和b;只是相当于对外转发了这两个接口
export {a as c, b} from './frank'
//趁机改个名字
export {default} from './frank'
export {default as sth} from './frank'
//默认接口
export * from './frank'
//暂不支持以下三种
import * as si from ''
import si from ''
import si, {si2} from ''
#3.3 模块的继承
export * from 'superModule' //export * 命令会忽略导入模块的default变量
export default 'subModule'
网友评论