溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

commonjs模塊與es6模塊有什么不同

發布時間:2021-02-03 17:30:03 來源:億速云 閱讀:324 作者:Leah 欄目:web開發

commonjs模塊與es6模塊有什么不同?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

commonjs

對于基本數據類型,屬于復制。即會被模塊緩存。同時,在另一個模塊可以對該模塊輸出的變量重新賦值。

對于復雜數據類型,屬于淺拷貝。由于兩個模塊引用的對象指向同一個內存空間,因此對該模塊的值做修改時會影響另一個模塊。

當使用require命令加載某個模塊時,就會運行整個模塊的代碼。

當使用require命令加載同一個模塊時,不會再執行該模塊,而是取到緩存之中的值。也就是說,commonjs模塊無論加載多少次,都只會在第一次加載時運行一次,以后再加載,就返回第一次運行的結果,除非手動清除系統緩存。

循環加載時,屬于加載時執行。即腳本代碼在require的時候,就會全部執行。一旦出現某個模塊被"循環加載",就只輸出已經執行的部分,還未執行的部分不會輸出。

ES6模塊

es6模塊中的值屬于【動態只讀引用】。

對于只讀來說,即不允許修改引入變量的值,import的變量是只讀的,不論是基本數據類型還是復雜數據類型。當模塊遇到import命令時,就會生成一個只讀引用。等到腳本真正執行時,再根據這個只讀引用,到被加載的那個模塊里面去取值。

對于動態來說,原始值發生變化,import加載的值也會發生變化。不論是基本數據類型還是復雜數據類型。

循環加載時,

上面說了一些重要區別?,F在舉一些例子來說明每一點吧

commonjs

對于基本數據類型,屬于復制。即會被模塊緩存。同時,在另一個模塊可以對該模塊輸出的變量重新賦值。

// b.js
let count = 1
let plusCount = () => {
 count++
}
setTimeout(() => {
 console.log('b.js-1', count)
}, 1000)
module.exports = {
 count,
 plusCount
}

// a.js
let mod = require('./b.js')
console.log('a.js-1', mod.count)
mod.plusCount()
console.log('a.js-2', mod.count)
setTimeout(() => {
 mod.count = 3
 console.log('a.js-3', mod.count)
}, 2000)

node a.js
a.js-1 1
a.js-2 1
b.js-1 2 // 1秒后
a.js-3 3 // 2秒后

以上代碼可以看出,b模塊export的count變量,是一個復制行為。在plusCount方法調用之后,a模塊中的count不受影響。同時,可以在b模塊中更改a模塊中的值。如果希望能夠同步代碼,可以export出去一個getter。

// 其他代碼相同
module.exports = {
 get count () {
 return count
 },
 plusCount
}

node a.js
a.js-1 1
a.js-2 1
b.js-1 2 // 1秒后
a.js-3 2 // 2秒后, 由于沒有定義setter,因此無法對值進行設置。所以還是返回2

對于復雜數據類型,屬于淺拷貝。由于兩個模塊引用的對象指向同一個內存空間,因此對該模塊的值做修改時會影響另一個模塊。

// b.js
let obj = {
 count: 1
}
let plusCount = () => {
 obj.count++
}
setTimeout(() => {
 console.log('b.js-1', obj.count)
}, 1000)
setTimeout(() => {
 console.log('b.js-2', obj.count)
}, 3000)
module.exports = {
 obj,
 plusCount
}

// a.js
var mod = require('./b.js')
console.log('a.js-1', mod.obj.count)
mod.plusCount()
console.log('a.js-2', mod.obj.count)
setTimeout(() => {
 mod.obj.count = 3
 console.log('a.js-3', mod.obj.count)
}, 2000)

node a.js
a.js-1 1
a.js-2 2
b.js-1 2
a.js-3 3
b.js-2 3

以上代碼可以看出,對于對象來說屬于淺拷貝。當執行a模塊時,首先打印obj.count的值為1,然后通過plusCount方法,再次打印時為2。接著在a模塊修改count的值為3,此時在b模塊的值也為3。

3.當使用require命令加載某個模塊時,就會運行整個模塊的代碼。

4.當使用require命令加載同一個模塊時,不會再執行該模塊,而是取到緩存之中的值。也就是說,commonjs模塊無論加載多少次,都只會在第一次加載時運行一次,以后再加載,就返回第一次運行的結果,除非手動清除系統緩存。

5.循環加載時,屬于加載時執行。即腳本代碼在require的時候,就會全部執行。一旦出現某個模塊被"循環加載",就只輸出已經執行的部分,還未執行的部分不會輸出。

3, 4, 5可以使用同一個例子說明

// b.js
exports.done = false
let a = require('./a.js')
console.log('b.js-1', a.done)
exports.done = true
console.log('b.js-2', '執行完畢')

// a.js
exports.done = false
let b = require('./b.js')
console.log('a.js-1', b.done)
exports.done = true
console.log('a.js-2', '執行完畢')

// c.js
let a = require('./a.js')
let b = require('./b.js')

console.log('c.js-1', '執行完畢', a.done, b.done)

node c.js
b.js-1 false
b.js-2 執行完畢
a.js-1 true
a.js-2 執行完畢
c.js-1 執行完畢 true true

仔細說明一下整個過程。

在Node.js中執行c模塊。此時遇到require關鍵字,執行a.js中所有代碼。

在a模塊中exports之后,通過require引入了b模塊,執行b模塊的代碼。

在b模塊中exports之后,又require引入了a模塊,此時執行a模塊的代碼。

a模塊只執行exports.done = false這條語句。

回到b模塊,打印b.js-1, exports, b.js-2。b模塊執行完畢。

回到a模塊,接著打印a.js-1, exports, b.js-2。a模塊執行完畢

回到c模塊,接著執行require,需要引入b模塊。由于在a模塊中已經引入過了,所以直接就可以輸出值了。

結束。

從以上結果和分析過程可以看出,當遇到require命令時,會執行對應的模塊代碼。當循環引用時,有可能只輸出某模塊代碼的一部分。當引用同一個模塊時,不會再次加載,而是獲取緩存。

ES6模塊

es6模塊中的值屬于【動態只讀引用】。只說明一下復雜數據類型。

對于只讀來說,即不允許修改引入變量的值,import的變量是只讀的,不論是基本數據類型還是復雜數據類型。當模塊遇到import命令時,就會生成一個只讀引用。等到腳本真正執行時,再根據這個只讀引用,到被加載的那個模塊里面去取值。

對于動態來說,原始值發生變化,import加載的值也會發生變化。不論是基本數據類型還是復雜數據類型。

// b.js
export let counter = {
 count: 1
}
setTimeout(() => {
 console.log('b.js-1', counter.count)
}, 1000)

// a.js
import { counter } from './b.js'
counter = {}
console.log('a.js-1', counter)

// Syntax Error: "counter" is read-only

雖然不能將counter重新賦值一個新的對象,但是可以給對象添加屬性和方法。此時不會報錯。這種行為類型與關鍵字const的用法。

// a.js
import { counter } from './b.js'
counter.count++
console.log(counter)

// 2

循環加載時,ES6模塊是動態引用。只要兩個模塊之間存在某個引用,代碼就能夠執行。

// b.js
import {foo} from './a.js';
export function bar() {
 console.log('bar');
 if (Math.random() > 0.5) {
 foo();
 }
}

// a.js
import {bar} from './b.js';
export function foo() {
 console.log('foo');
 bar();
 console.log('執行完畢');
}
foo();

node a.js
foo
bar
執行完畢

// 執行結果也有可能是
foo
bar
foo
bar
執行完畢
執行完畢

關于commonjs模塊與es6模塊有什么不同問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女