亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

詳解CommonJS和ES6模塊循環加載處理的區別

2024-05-06 16:47:18
字體:
來源:轉載
供稿:網友

CommonJS模塊規范使用require語句導入模塊,module.exports導出模塊,輸出的是值的拷貝,模塊導入的也是輸出值的拷貝,也就是說,一旦輸出這個值,這個值在模塊內部的變化是監聽不到的。

ES6模塊的規范是使用import語句導入模塊,export語句導出模塊,輸出的是對值的引用。ES6模塊的運行機制和CommonJS不一樣,遇到模塊加載命令import時不去執行這個模塊,只會生成一個動態的只讀引用,等真的需要用到這個值時,再到模塊中取值,也就是說原始值變了,那輸入值也會發生變化。

那CommonJS和ES6模塊規范針對模塊的循環加載處理機制有什么不同呢?

循環加載指的是a腳本的執行依賴b腳本,b腳本的執行依賴a腳本。

1. CommonJS模塊的加載原理

CommonJS模塊就是一個腳本文件,require命令第一次加載該腳本時就會執行整個腳本,然后在內存中生成該模塊的一個說明對象。

{  id: '', //模塊名,唯一  exports: { //模塊輸出的各個接口    ...  },  loaded: true, //模塊的腳本是否執行完畢  ...}

以后用到這個模塊時,就會到對象的exports屬性中取值。即使再次執行require命令,也不會再次執行該模塊,而是到緩存中取值。

CommonJS模塊是加載時執行,即腳本代碼在require時就全部執行。一旦出現某個模塊被“循環加載”,就只輸出已經執行的部分,沒有執行的部分不會輸出。

案例說明:

案例來源于Node官方說明: https://nodejs.org/api/modules.html#modules_cycles

//a.jsexports.done = false;var b = require('./b.js');console.log('在a.js中,b.done = %j', b.done);exports.done = true;console.log('a.js執行完畢!')
//b.jsexports.done = false;var a = require('./a.js');console.log('在b.js中,a.done = %j', a.done);exports.done = true;console.log('b.js執行完畢!')
//main.jsvar a = require('./a.js');var b = require('./b.js');console.log('在main.js中,a.done = %j, b.done = %j', a.done, b.done);

輸出結果如下:

//node環境下運行main.js
node main.js

在b.js中,a.done = false
b.js執行完畢!
在a.js中,b.done = true
a.js執行完畢!
在main.js中,a.done = true, b.done = true

JS代碼執行順序如下:
1)main.js中先加載a.js,a腳本先輸出done變量,值為false,然后加載b腳本,a的代碼停止執行,等待b腳本執行完成后,才會繼續往下執行。

2)b.js執行到第二行會去加載a.js,這時發生循環加載,系統會去a.js模塊對應對象的exports屬性取值,因為a.js沒執行完,從exports屬性只能取回已經執行的部分,未執行的部分不返回,所以取回的值并不是最后的值。

3)a.js已執行的代碼只有一行,exports.done = false;所以對于b.js來說,require a.js只輸出了一個變量done,值為false。往下執行console.log('在b.js中,a.done = %j', a.done);控制臺打印出:

在b.js中,a.done = false

4)b.js繼續往下執行,done變量設置為true,console.log('b.js執行完畢!'),等到全部執行完畢,將執行權交還給a.js。此時控制臺輸出:

b.js執行完畢!

5)執行權交給a.js后,a.js接著往下執行,執行console.log('在a.js中,b.done = %j', b.done);控制臺打印出:

在a.js中,b.done = true

6)a.js繼續執行,變量done設置為true,直到a.js執行完畢。

a.js執行完畢!

7)main.js中第二行不會再次執行b.js,直接輸出緩存結果。最后控制臺輸出:

在main.js中,a.done = true, b.done = true

總結:

1)在b.js中,a.js沒有執行完畢,只執行了第一行,所以循環加載中,只輸出已執行的部分。

2)main.js第二行不會再次執行,而是輸出緩存b.js的執行結果。exports.done = true;

2. ES6模塊的循環加載

ES6模塊與CommonJS有本質區別,ES6模塊是動態引用,遇到模塊加載命令import時不會去執行模塊,只是生成一個指向被加載模塊的引用,需要開發者保證真正取值時能夠取到值,只要引用是存在的,代碼就能執行。

案例說明:

//even.jsimport {odd} from './odd';var counter = 0;export function even(n){  counter ++;  console.log(counter);    return n == 0 || odd(n-1);}
//odd.jsimport {even} from './even.js';export function odd(n){  return n != 0 && even(n-1);}//index.jsimport * as m from './even.js';var x = m.even(5);console.log(x);var y = m.even(4);console.log(y);

執行index.js,輸出結果如下:

babel-node index.js

1
2
3
false
4
5
6
true

可以看出counter的值是累加的,ES6是動態引用。如果上面的引用改為CommonJS代碼,會報錯,因為在odd.js里,even.js代碼并沒有執行。

//改用CommonJS規范加載文件,執行會報錯var x = m.even(5);     ^TypeError: m.even is not a function  at Object.<anonymous> (/Users/zourong/Projects/node/ES6/mainx.1.js:3:11)  at Module._compile (internal/modules/cjs/loader.js:689:30)

3. 總結

1)CommonJS模塊是加載時執行。一旦出現某個模塊被“循環加載”,就只輸出已經執行的部分,沒有執行的部分不會輸出。

2)ES6模塊是動態引用,遇到模塊加載命令import時不會去執行模塊,只是生成一個指向被加載模塊的引用。

CommonJS模塊規范主要適用于后端Node.js,后端Node.js是同步模塊加載,所以在模塊循環引入時模塊已經執行完畢。推薦前端工程中使用ES6的模塊規范,通過安裝Babel轉碼插件支持ES6模塊引入的語法。

頁面內容主要來源于《ES6標準入門》Module 這一章的介紹。如果有描述不清楚或錯誤的地方,歡迎留言指證。

參考資料:

《ES6標準入門》之Module

Node.js Cycle

ES-Module-Loader

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产亚洲精品一区二555| 91大神在线播放精品| 欧美在线一区二区视频| 91wwwcom在线观看| 久久综合久久美利坚合众国| 日韩精品久久久久久福利| 欧美有码在线视频| 国产在线视频欧美| 日本一区二区三区在线播放| 亚洲已满18点击进入在线看片| 亚洲国产私拍精品国模在线观看| 九色成人免费视频| 国产精品美女久久久免费| 国语对白做受69| 欧美超级免费视 在线| 国产成人jvid在线播放| 久久久久久久一| 92版电视剧仙鹤神针在线观看| 亚洲国产精品久久久久| 日韩a**中文字幕| 久久久久久香蕉网| 国内外成人免费激情在线视频网站| 亚洲第一区第二区| 亚洲日本成人女熟在线观看| 国产精品久久久久久久久免费看| 91精品国产综合久久男男| 国产精品毛片a∨一区二区三区|国| 欧美日韩国产一区中文午夜| 日韩中文字幕在线免费观看| 欧美电影在线观看| 日韩国产欧美精品一区二区三区| 亚洲精品v欧美精品v日韩精品| 久久精品国产视频| 色妞色视频一区二区三区四区| 成人精品一区二区三区| 91免费精品国偷自产在线| xxxx欧美18另类的高清| 国产精品高潮呻吟久久av无限| 78色国产精品| 日韩av免费在线观看| 久久国产精品偷| 国产精品美女午夜av| 久久九九全国免费精品观看| 国产精品午夜一区二区欲梦| 欧美日韩在线视频一区二区| 日韩视频免费中文字幕| 精品国产区一区二区三区在线观看| 亚洲自拍欧美另类| 国产欧美日韩专区发布| 欧美中文在线视频| 国产成人精品999| 久久免费国产精品1| 97高清免费视频| 91精品国产色综合久久不卡98| 亚洲丝袜av一区| 日韩av一区二区在线| 91av在线免费观看| 色综合色综合久久综合频道88| 九九热视频这里只有精品| 亚洲跨种族黑人xxx| 亚洲男人天堂古典| 国产香蕉97碰碰久久人人| 亚洲欧美一区二区三区情侣bbw| 91久久精品美女高潮| 久久久91精品国产一区不卡| 欧美在线激情网| 国产精品久久久久久久天堂| 久久露脸国产精品| 日韩国产在线播放| 日韩在线激情视频| 国产精品一区二区久久久| 青青草国产精品一区二区| 尤物yw午夜国产精品视频| 亚洲人成电影网站| 精品免费在线视频| 国产97在线观看| 国产精品十八以下禁看| 亚洲视频在线观看| 午夜伦理精品一区| 欧美成人网在线| 欧美不卡视频一区发布| 欧美极品xxxx| 自拍偷拍亚洲一区| 亚洲热线99精品视频| 成人黄色av播放免费| 日本精品一区二区三区在线播放视频| 久久久久久久影院| 国产综合在线观看视频| 麻豆国产精品va在线观看不卡| 久久久久久久久久久亚洲| 亚洲视频在线观看| 欧美激情成人在线视频| 亚洲偷欧美偷国内偷| 日韩av色综合| 亚洲人成啪啪网站| 亚洲福利精品在线| 成人在线激情视频| 亚洲一区av在线播放| 久久夜精品va视频免费观看| 精品国产乱码久久久久久虫虫漫画| 亚洲人成网站色ww在线| 久久久久免费视频| 国产精品视频区| 中文字幕国内精品| 91av在线影院| 午夜精品一区二区三区在线视频| 精品欧美aⅴ在线网站| 热99精品只有里视频精品| 欧美精品久久久久a| 高清欧美性猛交xxxx黑人猛交| 波霸ol色综合久久| 欧洲亚洲免费在线| 2018中文字幕一区二区三区| 国产精品稀缺呦系列在线| 国产精品久久久久久久9999| 亚洲欧美国产一区二区三区| 亚洲jizzjizz日本少妇| 亚洲电影免费观看高清| 成人免费自拍视频| 黑人巨大精品欧美一区二区免费| 国产视频自拍一区| 久久久久久这里只有精品| 国产精品999999| 亚洲国产97在线精品一区| 久久久久久久久久国产精品| 欧美日韩国产123| 亚洲精品成人久久| 久久精品色欧美aⅴ一区二区| 91亚洲精品久久久| 欧美成人国产va精品日本一级| 亚洲国产精品久久精品怡红院| 少妇久久久久久| 久久精品国产久精国产思思| 色yeye香蕉凹凸一区二区av| 国产噜噜噜噜噜久久久久久久久| 亚洲日本中文字幕| 最近中文字幕日韩精品| 成人有码视频在线播放| 欧美视频在线观看免费网址| 成人做爽爽免费视频| 亚洲激情在线观看| 日韩欧美在线视频免费观看| 欧美亚洲国产另类| 国产成人一区三区| 久久久天堂国产精品女人| 成人av电影天堂| 中文字幕精品一区二区精品| 久久九九全国免费精品观看| 亚洲精品网站在线播放gif| 国产精品综合久久久| 国产自摸综合网| 亚洲成人网久久久| 在线电影欧美日韩一区二区私密| 狠狠躁天天躁日日躁欧美| 久久精品91久久久久久再现| 热re99久久精品国产66热| 一色桃子一区二区| 国产精品久久99久久| 国产精品三级久久久久久电影| 久久久久久香蕉网| 亚洲国产高清自拍| 亚洲免费高清视频| 日韩中文字幕在线精品| 欧美日韩精品在线视频|