1. 概述
由于 ES6 模塊是編譯時加載,使得靜態(tài)分析成為可能。有了它,就能進一步拓寬 JavaScript 的語法,比如引入宏(macro)和類型檢驗(type system)這些只能靠靜態(tài)分析實現(xiàn)的功能偿短。
除了靜態(tài)加載帶來的各種好處,ES6 模塊還有以下好處馋没。
不再需要UMD
模塊格式了昔逗,將來服務(wù)器和瀏覽器都會支持 ES6 模塊格式。目前篷朵,通過各種工具庫勾怒,其實已經(jīng)做到了這一點。
將來瀏覽器的新 API 就能用模塊格式提供款票,不再必須做成全局變量或者navigator
對象的屬性控硼。
不再需要對象作為命名空間(比如Math
對象),未來這些功能可以通過模塊提供艾少。
2. 嚴格模式
ES6 的模塊自動采用嚴格模式卡乾,不管你有沒有在模塊頭部加上"use strict"
;。
嚴格模式主要有以下限制缚够。
變量必須聲明后再使用
函數(shù)的參數(shù)不能有同名屬性幔妨,否則報錯
不能使用with
語句
不能對只讀屬性賦值,否則報錯
不能使用前綴0
表示八進制數(shù)谍椅,否則報錯
不能刪除不可刪除的屬性误堡,否則報錯
不能刪除變量delete prop
,會報錯雏吭,只能刪除屬性delete global[prop]
eval
不會在它的外層作用域引入變量
eval
和arguments
不能被重新賦值
arguments
不會自動反映函數(shù)參數(shù)的變化
不能使用arguments.callee
不能使用arguments.caller
禁止this
指向全局對象
不能使用fn.caller
和fn.arguments
獲取函數(shù)調(diào)用的堆棧
增加了保留字(比如protected
锁施、static
和interface
)
3. export 命令
模塊功能主要由兩個命令構(gòu)成:export
和import
。export
命令用于規(guī)定模塊的對外接口,import
命令用于輸入其他模塊提供的功能悉抵。
// 寫法一
export var m = 1;
// 寫法二
var m = 1;
export {m};
// 寫法三
var n = 1;
export {n as m};
最后肩狂,export
命令可以出現(xiàn)在模塊的任何位置,只要處于模塊頂層就可以姥饰。如果處于塊級作用域內(nèi)傻谁,就會報錯,下一節(jié)的import
命令也是如此列粪。這是因為處于條件代碼塊之中审磁,就沒法做靜態(tài)優(yōu)化了,違背了 ES6 模塊的設(shè)計初衷岂座。
4. import 命令
使用export
命令定義了模塊的對外接口以后态蒂,其他 JS 文件就可以通過import
命令加載這個模塊。
最后费什,import
語句會執(zhí)行所加載的模塊吃媒,因此可以有下面的寫法。
import { foo } from 'my_module';
import { bar } from 'my_module';
// 等同于
import { foo, bar } from 'my_module';
5. 模塊的整體加載
除了指定加載某個輸出值吕喘,還可以使用整體加載,即用星號(*
)指定一個對象刑桑,所有輸出值都加載在這個對象上面氯质。
// circle.js 導(dǎo)出模塊
export function area(radius) {
return Math.PI * radius * radius;
}
export function circumference(radius) {
return 2 * Math.PI * radius;
}
// 整體引入
import * as circle from './circle';
console.log('圓面積:' + circle.area(4));
console.log('圓周長:' + circle.circumference(14));
6. export default 命令
為了給用戶提供方便,讓他們不用閱讀文檔就能加載模塊祠斧,就要用到export default
命令闻察,為模塊指定默認輸出。
// export-default.js
export default function foo() {
console.log('foo');
}
// 或者寫成
function foo() {
console.log('foo');
}
export default foo;
如果想在一條import
語句中琢锋,同時輸入默認方法和其他接口辕漂,可以寫成下面這樣。
import _, { each, each as forEach } from 'lodash';
7. export 與 import 的復(fù)合寫法
如果在一個模塊之中吴超,先輸入后輸出同一個模塊钉嘹,import
語句可以與export
語句寫在一起。
export { foo, bar } from 'my_module';
// 可以簡單理解為
import { foo, bar } from 'my_module';
export { foo, bar };
模塊的接口改名和整體輸出鲸阻,也可以采用這種寫法跋涣。
export { es6 as default } from './someModule';
// 等同于
import { es6 } from './someModule';
export default es6;
8. 模塊的繼承
假設(shè)有一個circleplus
模塊,繼承了circle
模塊鸟悴。
// circleplus.js
export * from 'circle';
export var e = 2.71828182846;
export default function(x) {
return Math.exp(x);
}
9. 跨模塊常量
本書介紹 const 命令的時候說過陈辱, const 聲明的常量只在當(dāng)前代碼塊有效。如果想設(shè)置跨模塊的常量(即跨多個文件)细诸,或者說一個值要被多個模塊共享沛贪,可以采用下面的寫法。
// constants.js 模塊
export const A = 1;
export const B = 3;
export const C = 4;
// test1.js 模塊
import * as constants from './constants';
console.log(constants.A); // 1
console.log(constants.B); // 3
// test2.js 模塊
import {A, B} from './constants';
console.log(A); // 1
console.log(B); // 3
10. import()
因此,有一個提案利赋,建議引入import()
函數(shù)水评,完成動態(tài)加載。
import()
返回一個 Promise 對象隐砸。下面是一個例子之碗。