天天看點

JS-學習ES6之-ES6子產品化的注意點目錄1、概述2、使用方法和注意點參考資料

目錄

  • 概述
  • 使用方法和注意點

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 { '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

語句,那麼隻會執行一次,而不會執行多次。
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 ;

// 報錯
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

子產品輸出的是值的緩存,不存在動态更新。

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 的文法

繼續閱讀