Module

1.ES6在語言標準的層面上,實現了模組功能,成為瀏覽器和伺服器通用的模組解決方案,完全可以取代 CommonJS 和 AMD 規範,基本特點如下:

  • 每一個模組只加載一次, 每一個JS只執行一次, 如果下次再去載入同目錄下同檔案,直接從記憶體中讀取;
  • 每一個模組內宣告的變數都是區域性變數, 不會汙染全域性作用域;
  • 模組內部的變數或者函式可以通過export匯出;
  • 一個模組可以匯入別的模組

2.模組功能主要由兩個命令構成:export和import。export命令用於規定模組的對外介面,import命令用於輸入其他模組提供的功能;

3.一個模組就是一個獨立的檔案,該檔案內部的所有變數,外部無法獲取。如果你希望外部能夠讀取模組內部的某個變數,就必須使用export關鍵字輸出該變數;

// profile.js
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958; //或者
// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958; export {firstName, lastName, year};

4.export命令除了輸出變數,還可以輸出函式或類(class)

export function multiply(x, y) {
return x * y;
};

一般來說,export 輸出的變數就是本來的名字,但是可以使用 as 關鍵字重新命名

function Module1() { ... }
function Module2() { ... } export {
Module1 as Func1,
Module2 as Func2
};

5.export語句輸出的介面,與其對應的值是動態繫結關係,即通過該介面,可以取到模組內部實時的值;

export var str = 'hello';
setTimeout(() => str = 'world', 1000);
console.log(str)

上面程式碼輸出變數str,值為hello,1秒之後變成world。

6.export命令可以出現在模組的任何位置,只要處於模組頂層就可以。如果處於塊級作用域內,就會報錯;

function foo() {
export default 'bar' // SyntaxError
}
foo()

7.使用export命令定義了模組的對外介面以後,其他 JS 檔案就可以通過import命令載入這個模組,import命令接受一對大括號,裡面指定要從其他模組匯入的變數名,大括號裡面的變數名,必須與被匯入模組(profile.js)對外介面的名稱相同;

// main.js
import {firstName, lastName, year} from './profile'; function say() {
console.log('Hello , ' + firstName + ' ' + lastName);
}

上面程式碼的 import 用於載入 profile.js 檔案,並從中輸入變數。

8.如果想為輸入的變數重新取一個名字,也可以使用 as 關鍵字,將輸入的變數重新命名。

import { lastName as secondName } from './profile';

9.import 後面的 from 指定模組檔案的位置,可以是相對路徑,也可以是絕對路徑,.js字尾可以省略。如果只是模組名,不帶有路徑,那麼必須有配置檔案,告訴 JavaScript 引擎該模組的位置;

import { methods } from 'util';

10.import命令具有提升效果,會提升到整個模組的頭部,首先執行

func();

import { func } from 'methods';

上面的程式碼不會報錯,因為 import 的執行早於 func 的呼叫。因為 import 命令是編譯階段執行的;

11.由於import是靜態執行,所以不能使用表示式和變數

// 報錯
import { 'f' + 'oo' } from 'methods'; // 報錯
let module = 'methods';
import { foo } from module; // 報錯
if (x === 1) {
import { foo } from 'module1';
} else {
import { foo } from 'module2';
}

上面三種寫法都會報錯,因為它們用到了表示式、變數和 if 結構。在靜態分析階段,這些語法都是沒法得到值的;

12.import 除了指定載入某個輸出值,還可以使用整體載入,即用星號(*)指定一個物件,所有輸出值都載入在這個物件上面

// tools

export function circleArea(r){
return Math.PI * r * r ;
} export function rectArea( w , h ){
return w * h ;
} // main.js
//逐一載入
import { circleArea , rectArea } from './tools'; console.log( '圓的面積是:' + circleArea( 5 ) );
console.log( '矩形的面積是:' + rectArea( 5 , 6 ) ); //整體載入
import * as area from './tools'; console.log( '圓的面積是:' + area.circleArea( 5 ) );
console.log( '矩形的面積是:' + area.rectArea( 5 , 6 ) );

不要嘗試去在執行時去改變模組整體載入所在的物件(即上例中的area)的值,是不允許的;

13.export default命令,為模組指定預設輸出,這樣就可以在使用 import 命令的時候,不必知道所要載入的變數名或函式名;

// export-default.js
export default function () {
console.log('foo');
} // import-default.js
import customName from './export-default';
customName();
// 'foo'

上面程式碼是一個模組檔案 export-default.js,它的預設輸出是一個函式,在其他模組載入該模組時,import 命令可以為該匿名函式指定任意名字,這時import命令後面,不使用大括號;

14.export default命令用在非匿名函式前,也是可以的。

// export-default.js
export default function foo() {
console.log('hello world');
} // 或者寫成 function foo() {
console.log('hello world');
} export default foo;

要注意的是,一個模組只能有一個預設輸出,因此 export default 命令只能使用一次。所以,import 命令後面才不用加大括號,因為只可能對應一個方法;實際本質上,export default 就是輸出一個叫做 default 的變數或方法,系統允許你為它取任意名字;

// modules.js
function add(x, y) {
return x + y;
}
export { add as default };
// 等同於
// export default add; // app.js
import { default as xxx } from 'modules';
// 等同於
// import xxx from 'modules';

15.由於 export default 命令其實只是輸出一個叫做default的變數,所以它後面不能跟變數宣告語句;

// 正確
export var a = 1; // 正確
var a = 1;
export default a; //等同於將變數 a 的值賦給變數 default // 錯誤
export default var a = 1;

16.export default也可以用來輸出類。

// MyClass.js
export default class { ... } // main.js
import MyClass from 'MyClass';
let o = new MyClass();

17.如果在一個模組之中,先輸入後輸出同一個模組,import語句可以與export語句寫在一起;

export { foo, bar } from 'module';

// 等同於
import { foo, bar } from 'module';
export { foo, bar };

18.const宣告的常量只在當前程式碼塊有效。如果想設定跨模組的常量(即跨多個檔案),或者說一個值要被多個模組共享,可以採用下面的寫法:

// constants.js 模組
export const A = 1;
export const B = 2; // test1.js 模組
import * as constants from './constants';
console.log(constants.A); // 1
console.log(constants.B); // 2 // test2.js 模組
import {A, B} from './constants';
console.log(A); // 1
console.log(B); // 2

作者:Cryptic
連結:https://www.jianshu.com/p/3d69d4ac2dfe
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。