1. 程式人生 > 其它 >CommonJS模組與ES6模組的區別

CommonJS模組與ES6模組的區別

一.CommonJS模組與ES6模組的區別

  1. CommonJS模組輸出的是一個值的拷貝,ES6模組輸出的是值的引用
  2. CommonJS模組是執行時載入,ES6模組是編譯時輸出介面
  3. CommonJS模組的require()是同步載入模組,ES6模組的import命令是非同步載入,有一個獨立的模組依賴的解析階段。

  第二個區別是因為CommonJS載入的是一個物件(即module.exports屬性),該物件只有在指令碼執行完才會生成。而ES6模組不是物件,它的對外介面只是一種靜態定義,在程式碼靜態解析階段就會生成。

  第一個區別

  CommonJS模組輸出的是值的拷貝,也就是說,一旦輸出一個值,模組內部的變化就影響不到這個值。例如:

  

  上面程式碼輸出內部變數counter和改寫這個變數的內部方法incCounter。然後,在main.js裡面載入這個模組。

  

  上面程式碼說明,lib.js模組載入之後,它的內部變化就影響不到輸出的mod.counter了。這是因為mod.counter是一個原始型別的值,會被快取。除非寫成一個函式,才能得到內部的值。例如:

  

  上面程式碼中,輸出的counter屬性實際上是一個取值器函式。現在再執行main.js,就可以正確讀取內部變數counter的變動了。

  

  ES6模組的執行機制與CommonJS不一樣。JS引擎對指令碼靜態分析的時候,遇到模組載入命令import

,就會生成一個只讀引用。等到指令碼真正執行時,再根據這個只讀引用,到被載入的那個模組裡面去取值。例如:

  

  上面程式碼說明,ES6模組輸入的變數counter是活的,完全反應其所在模組lib.js內部的變化。

  再說一個出現在export中的例子:

  

  

  上面程式碼表明,ES6模組不會快取執行結果,而是動態地去被載入模組取值,並且變數總是繫結其所在的模組。

  

  上面程式碼中,main.jslib.js輸入變數obj,可以對obj新增屬性,但是不能重新賦值。因為變數的地址是隻讀的

  最後,export通過介面,輸出的是同一個值。不同的指令碼載入這個介面,得到的都是同樣的例項。例如:

  

  上面的指令碼mod.js,輸出的是一個c的例項。不同的指令碼載入這個模組,得到的都是同一個例項。

  

  

  這就證明了x.jsy.js載入的都是c的同一個例項。