目錄
- 概述
- 使用方法和注意點
1、概述
一直以來 javascript 的子產品化要麼使用
commonJS
,要麼使用
AMD
,在 ES6 中開始支援子產品化了,關鍵字主要有
import
(導入)和
export
(導出)。最近一段時間一直在思考 ES6 中的子產品化與我們正常使用的
AMD
( 如
requireJS
),以及
commomJS
(如
nodeJS
)有何不同。在搜尋了相關的資料後,發現 ES6 子產品化中有些地方很值得注意。
2、使用方法和注意點
2.1 ES6子產品是靜态加載
ES6 子產品的設計思想,是盡量的靜态化,使得編譯時就能确定子產品的依賴關系,以及輸入和輸出的變量。
CommonJS
和
AMD
子產品,都隻能在運作時确定這些東西。
import
和
export
指令可以出現在子產品的任何位置,隻要處于子產品頂層就可以。如果處于塊級作用域内,就會報錯。這是因為處于條件代碼塊之中,就沒法做靜态優化了,違背了 ES6 子產品的設計初衷。以下的寫法會報錯
// 報錯
if (x === ) {
import { foo } from 'module1';
} else {
import { foo } from 'module2';
}
// 報錯
function foo() {
export default 'bar' // SyntaxError
}
foo()
2.2 import
2.2.1 由于 import
是靜态執行,是以不能使用表達式和變量,這些隻有在運作時才能得到結果的文法結構。
import
// 報錯
import { 'f' + 'oo' } from 'my_module';
// 報錯
let module = 'my_module';
import { foo } from module;
// 報錯
if (x === ) {
import { foo } from 'module1';
} else {
import { foo } from 'module2';
}
上面三種寫法都會報錯,因為它們用到了表達式、變量和
if
結構。在靜态分析階段,這些文法都是沒法得到值的。
2.2.2 import
語句會執行所加載的子產品.如果多次重複執行同一句 import
語句,那麼隻會執行一次,而不會執行多次。
import
import
2.2.3 子產品的整體加載
// circle.js
export function area(radius) {
return Math.PI * radius * radius;
}
export function circumference(radius) {
return * Math.PI * radius;
}
// main.js
import * as circle from './circle';
console.log('圓面積:' + circle.area());
console.log('圓周長:' + circle.circumference());
注意,子產品整體加載所在的那個對象(上例是
circle
),應該是可以靜态分析的,是以不允許運作時改變。下面的寫法都是不允許的。
//main.js
import * as circle from './circle';
// 下面兩行都是不允許的
circle.foo = 'hello';
circle.area = function () {};
2.3 export
2.3.1 export
指令規定的是對外的接口,必須與子產品内部的變量建立一一對應關系。
export
// 報錯
export ;
// 報錯
var m = ;
export m;
上面兩種寫法都會報錯,因為沒有提供對外的接口。第一種寫法直接輸出1,第二種寫法通過變量m,還是直接輸出1。1隻是一個值,不是接口。正确的寫法是下面這樣。
// 寫法一
export var m = ;
// 寫法二
var m = ;
export {m};
// 寫法三
var n = ;
export {n as m};
上面三種寫法都是正确的,規定了對外的接口m。其他腳本可以通過這個接口,取到值1。它們的實質是,在接口名與子產品内部變量之間,建立了一一對應的關系。
2.3.2 export
語句輸出的接口,與其對應的值是動态綁定關系,即通過該接口,可以取到子產品内部實時的值。這一點與 CommonJS
規範完全不同。 CommonJS
子產品輸出的是值的緩存,不存在動态更新。
export
CommonJS
CommonJS
2.4 export 和 import 使用的例子
2.4.1 export {} + import {}
// jq.js
function myfun () {
console.log('excuted');
}
export {
myfun
}
引入方式:
import {myfun} from 'js/jq';
//執行
myfun();
2.4.2 export {} + import * as xxx
// jq.js
function myfun () {
console.log('excuted');
}
export {
myfun
}
引入方式:
import * as fn from 'js/jq';
//執行
fn.myfun();
2.4.3 import default + export xxx
// jq.js
function myfun () {
console.log('excuted');
}
export default {
myfun
}
引入方式:
import fn from 'js/jq';
//執行
fn.myfun();
參考資料
ECMAScript 6 入門-Module 的文法