如圖 5 所示,模塊 A 依賴模塊 B,模塊 B 又依賴模塊 A,模塊 A 和 B 分別被 require 語句從上往下分為 2 段,記為 A1、A2、B1、B2 。

文章插圖
如圖 6 所示,代碼塊的執(zhí)行順序?yàn)椋篈1 -> B1 -> B2 -> A2 。

文章插圖
使用不當(dāng)?shù)膯栴}如果 B2 使用了 A2 導(dǎo)出的變量會(huì)怎么樣呢?模塊 A 的模塊對象上不存在該變量對應(yīng)的屬性,獲取的值為 undefined 。獲得 undefined 雖然不符合預(yù)期,但一般不會(huì)造成 JS 錯(cuò)誤 。
可以看到,由于 require 語句直接分割了執(zhí)行的代碼塊,CommonJS 模塊的導(dǎo)入導(dǎo)出語句的位置會(huì)影響模塊代碼語句的執(zhí)行結(jié)果 。
ES6 模塊ES6 模塊[4]借助 JS 引擎實(shí)現(xiàn) 。JS 引擎實(shí)現(xiàn)了 ES6 模塊的底層核心邏輯,JS 運(yùn)行時(shí)需要在上層做適配 。適配工作量還不小,比如實(shí)現(xiàn)文件的加載,具體可以看一下我發(fā)起的一個(gè)討論[5] 。
模塊使用報(bào)錯(cuò)ES6 模塊使用不當(dāng)時(shí),由 JS 引擎或 JS 運(yùn)行時(shí)的適配層拋出錯(cuò)誤 。比如:
// Node.js 中報(bào)錯(cuò) internal/process/esm_loader.js:74 internalBinding('errors').triggerUncaughtException ^ Error [ERR_MODULE_NOT_FOUND]: Cannot find module // 瀏覽器中報(bào)錯(cuò) Uncaught SyntaxError: The requested module './child.js' does not provide an export named 'b'第一個(gè)是 Node.js 適配層觸發(fā)的內(nèi)部錯(cuò)誤(不是通過 throw 拋出的),第二個(gè)是瀏覽器拋出的 JS 引擎級別的語法錯(cuò)誤 。
模塊執(zhí)行順序ES6 模塊有 5 種狀態(tài),分別為 unlinked、linking、linked、evaluating 和 evaluated,用循環(huán)模塊記錄(Module Environment Records)[6]的 Status 字段表示 。ES6 模塊的處理包括連接(link)和評估(evaluate)兩步 。連接成功之后才能進(jìn)行評估 。
連接主要由函數(shù) InnerModuleLinking[7] 實(shí)現(xiàn) 。函數(shù) InnerModuleLinking 會(huì)調(diào)用函數(shù) InitializeEnvironment[8],該函數(shù)會(huì)初始化模塊的環(huán)境記錄(Environment Records)[9],主要包括創(chuàng)建模塊的執(zhí)行上下文(Execution Contexts)[10]、給導(dǎo)入模塊變量創(chuàng)建綁定[11]并初始化[12]為子模塊的對應(yīng)變量,給 var 變量創(chuàng)建綁定并初始化為 undefined、給函數(shù)聲明變量創(chuàng)建綁定并初始化為函數(shù)體的實(shí)例化[13]值、給其他變量創(chuàng)建綁定但不進(jìn)行初始化 。
對于圖 3 的模塊關(guān)系,連接過程如圖 7 所示 。連接階段采用深度優(yōu)先遍歷,通過函數(shù) HostResolveImportedModule[14] 獲取子模塊 。完成核心操作的函數(shù) InitializeEnvironment 是后置執(zhí)行的,所以從效果上看,子模塊先于父模塊被初始化 。

文章插圖
評估主要由函數(shù) InnerModuleEvaluation[15] 實(shí)現(xiàn) 。函數(shù) InnerModuleEvaluation 會(huì)調(diào)用函數(shù) ExecuteModule[16],該函數(shù)會(huì)評估模塊代碼(evaluating module.[[ECMAScriptCode]]) 。ES6 規(guī)范并沒有明確說明這里的評估模塊代碼具體指什么 。我把 ES6 規(guī)范的相關(guān)部分反復(fù)看了至少十余遍,才得出一個(gè)比較合理的解釋 。這里的評估模塊代碼應(yīng)該指根據(jù)代碼語句順序執(zhí)行條款 13[17]、條款 14[18] 和 條款 15[19] 內(nèi)的對應(yīng)小節(jié)的“運(yùn)行時(shí)語義:評估(Runtime Semantics: Evaluation)” 。ScriptEvaluation[20] 中的評估腳本(evaluating scriptBody)應(yīng)該也是這個(gè)意思 。可以看到,ES6 規(guī)范雖然做了很多設(shè)計(jì)并且邏輯清晰和自洽,但仍有一些模棱兩可的地方,沒有達(dá)到一種絕對完善和無懈可擊的狀態(tài) 。
對于圖 3 的模塊關(guān)系,評估過程如圖 8 所示 。和連接階段類似,評估階段也采用深度優(yōu)先遍歷,通過函數(shù) HostResolveImportedModule 獲取子模塊 。完成核心操作的函數(shù) ExecuteModule 是后置執(zhí)行的,所以從效果上看,子模塊先于父模塊被執(zhí)行 。
以上關(guān)于本文的內(nèi)容,僅作參考!溫馨提示:如遇健康、疾病相關(guān)的問題,請您及時(shí)就醫(yī)或請專業(yè)人士給予相關(guān)指導(dǎo)!
「愛刨根生活網(wǎng)」www.malaban59.cn小編還為您精選了以下內(nèi)容,希望對您有所幫助:- 怎么發(fā)面好 怎樣發(fā)面,如何發(fā)好面
- 現(xiàn)在網(wǎng)絡(luò)上流行什么詞
- 70年代的縫紉機(jī)現(xiàn)在值多少錢 70年代縫紉機(jī)回收價(jià)格
- “哭暈在廁所”這個(gè)網(wǎng)絡(luò)用語怎么來的?是什么意思
- 再開個(gè)店都綽綽有余 女子十年在美發(fā)店消費(fèi)150萬
- 你支持現(xiàn)在的網(wǎng)絡(luò)用語嗎?各種縮寫,諧音相繼面世是好是壞?
- 劉德華鍛煉腹肌 每天有適量運(yùn)動(dòng)
- 女性在家徒手訓(xùn)練打造翹臀
- 蘋果在生活中的妙用
- 某年墨西哥等國出現(xiàn)了流感疫情,引發(fā)全球關(guān)注.在協(xié)助墨西哥等國家防控疫情傳播過程中發(fā)揮重要作用的國際
