ES模組語法學習小記

Aiyomaya發表於2018-08-08

原文:es6.ruanyifeng.com/#docs/modul…

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'
複製程式碼

相關文章