ES6 module加載機制

找遍度娘,發現好多文章都是拿來主義,阮一峯老師ECMAScript6入門的文檔各類花式開枝散葉,語法上阮一峯老師講的已經很是細緻了,可是概念上的東西我仍是有點模糊。es6

文檔裏講了ES6模塊加載和CommonJS的區別(ES5的模塊引用表現形式可能有些不一樣,但本質其實都是把模塊做爲對象引用,因此這個區別也是ES6和ES5模塊引用的區別):bash

1.CommonJS 模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的引用ui

2.CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出接口。google

我這人比較懶,不太習慣單純的copy,強烈推薦你們先看一下阮一峯老師的ECMAScript 6 入門spa

文檔裏針對這兩點作了詳細的解釋,針對第一點解釋說ES6 模塊不是對象,那我就想知道不是對象他究竟是什麼,百度了很久,終於在google搜索的第一篇的文章裏找到了答案:3d

每個 ES6 模塊都是一個包含 JS 代碼的文件,模塊本質上就是一段腳本,而不是用module關鍵字定義一個模塊。其實我想知道的就是這句話, ES6 模塊是腳本。code

根據上面獲得的概念,不難理解CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出接口。 CommonJS的模塊本質是一個對象的引用,所以須要運行時加載。而ES6的module其實就是引入了一個新的概念,模塊不是對象而是腳本,這樣就能夠在編譯的時候加載。cdn

至於CommonJS 模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的引用。這個點咱們能夠想象一下import和export到底作了什麼,它們在程序加載的時候組成一對不一樣於"="的對應關係。對象

舉個例子
case1 CommonJS模塊引用blog

//a.js
let func=require('./b').func,
     a=require('./b').b;
a=1;
func();//輸出2

//b.js
let b=2;
function func() {
    console.log(b);
}
module.exports = {
    func: func,
    b: b
};
複製代碼

case2 ES6模塊引用

//a.mjs
import {b as a}  from "./b.mjs"
import {func}  from "./b.mjs"
a=1;//報錯
func();

//b.mjs
export function func() {
    console.log(b)
}
export let b=2;
複製代碼

再來一張在下的大做

正常狀況下,咱們把一個存放值的變量b賦值給變量a,其實就是把b裏面存放的值放進a的存儲空間中,這一點沒什麼異議。而case1這種狀況,CommonJS 模塊是一個正常的JS對象,a=require('./b').b等同於a=b 因此遵循JS的變量賦值的規則。

ES6 模塊輸出的是值的引用。在ES6中,case3這種狀況下,若是咱們試圖直接修改a的值會報錯,由於a不是b,a是指向變量b的變量,若是要修改a的值,只有在被引用的模塊裏修改b的值,a的值纔會發生改變。因此咱們能夠認爲export和import帶來的關係是,a的存儲空間指向變量b,而且這個關係不能夠被破壞。

參考

[深刻淺出 ES6(十六):模塊 Modules]www.infoq.cn/article/es6… ECMAScript 6 入門

相關文章
相關標籤/搜索