最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解CommonJS和ES6模塊循環(huán)加載處理的區(qū)別

 更新時間:2018年12月26日 15:18:43   作者:鄒R-ainna  
這篇文章主要介紹了詳解CommonJS和ES6模塊循環(huán)加載處理的區(qū)別,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

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

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

那CommonJS和ES6模塊規(guī)范針對模塊的循環(huán)加載處理機制有什么不同呢?

循環(huán)加載指的是a腳本的執(zhí)行依賴b腳本,b腳本的執(zhí)行依賴a腳本。

1. CommonJS模塊的加載原理

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

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

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

CommonJS模塊是加載時執(zhí)行,即腳本代碼在require時就全部執(zhí)行。一旦出現(xiàn)某個模塊被“循環(huán)加載”,就只輸出已經(jīng)執(zhí)行的部分,沒有執(zhí)行的部分不會輸出。

案例說明:

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

//a.js
exports.done = false;

var b = require('./b.js');
console.log('在a.js中,b.done = %j', b.done);

exports.done = true;
console.log('a.js執(zhí)行完畢!')
//b.js
exports.done = false;

var a = require('./a.js');
console.log('在b.js中,a.done = %j', a.done);

exports.done = true;
console.log('b.js執(zhí)行完畢!')

//main.js
var a = require('./a.js');
var b = require('./b.js');

console.log('在main.js中,a.done = %j, b.done = %j', a.done, b.done);

輸出結(jié)果如下:

//node環(huán)境下運行main.js
node main.js

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

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

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

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

在b.js中,a.done = false

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

b.js執(zhí)行完畢!

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

在a.js中,b.done = true

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

a.js執(zhí)行完畢!

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

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

總結(jié):

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

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

2. ES6模塊的循環(huán)加載

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

案例說明:

//even.js
import {odd} from './odd';

var counter = 0;
export function even(n){
  counter ++;
  console.log(counter);
  
  return n == 0 || odd(n-1);
}

//odd.js
import {even} from './even.js';

export function odd(n){
  return n != 0 && even(n-1);
}

//index.js
import * as m from './even.js';

var x = m.even(5);
console.log(x);

var y = m.even(4);
console.log(y);

執(zhí)行index.js,輸出結(jié)果如下:

babel-node index.js

1
2
3
false
4
5
6
true

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

//改用CommonJS規(guī)范加載文件,執(zhí)行會報錯
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. 總結(jié)

1)CommonJS模塊是加載時執(zhí)行。一旦出現(xiàn)某個模塊被“循環(huán)加載”,就只輸出已經(jīng)執(zhí)行的部分,沒有執(zhí)行的部分不會輸出。

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

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

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

參考資料:

《ES6標準入門》之Module

Node.js Cycle

ES-Module-Loader

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • JS實現(xiàn)的加減乘除四則運算計算器示例

    JS實現(xiàn)的加減乘除四則運算計算器示例

    這篇文章主要介紹了JS實現(xiàn)的加減乘除四則運算計算器,涉及javascript事件響應及數(shù)學運算相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • 在table中插入多行,能使用與insertAdjacentHTML相似的功能嗎?

    在table中插入多行,能使用與insertAdjacentHTML相似的功能嗎?

    在table中插入多行,能使用與insertAdjacentHTML相似的功能嗎?...
    2006-12-12
  • mui上拉加載功能實例詳解

    mui上拉加載功能實例詳解

    最近小編在做移動端的項目,用到了mui的上拉加載功能,今天小編給大家整理一下分享到腳本之家平臺,需要的朋友參考下
    2017-04-04
  • Javascript 顏色漸變效果的實現(xiàn)代碼

    Javascript 顏色漸變效果的實現(xiàn)代碼

    在搭建博主博客的時候,尋思著做一些效果,看到菜單,就想是不是可以做一下顏色的漸變,增加一點動態(tài)的感覺。有個jquery的插件,效果相當不錯,不過博主還是打算自立更生寫一下,看看能不能實現(xiàn)
    2013-10-10
  • js老生常談之this,constructor ,prototype全面解析

    js老生常談之this,constructor ,prototype全面解析

    下面小編就為大家?guī)硪黄猨s老生常談之this,constructor ,prototype。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-04-04
  • JavaScript中創(chuàng)建原子的方法總結(jié)

    JavaScript中創(chuàng)建原子的方法總結(jié)

    這篇文章主要給大家總結(jié)介紹了關(guān)于JavaScript中創(chuàng)建原子的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-08-08
  • ES6新特性三: Generator(生成器)函數(shù)詳解

    ES6新特性三: Generator(生成器)函數(shù)詳解

    這篇文章主要介紹了ES6新特性之Generator(生成器)函數(shù),簡單分析了Generator(生成器)函數(shù)的功能、定義、調(diào)用方法并結(jié)合實例形式給出了相關(guān)使用技巧,需要的朋友可以參考下
    2017-04-04
  • ES6字符串和數(shù)值新增方法總結(jié)

    ES6字符串和數(shù)值新增方法總結(jié)

    ES6為js新增了很多方法,包括遍歷、查詢、替換等等,下面這篇文章主要給大家介紹了關(guān)于ES6字符串和數(shù)值新增方法的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-09-09
  • console.log()的作用與實現(xiàn)方式

    console.log()的作用與實現(xiàn)方式

    這篇文章主要介紹了console.log()的作用與實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 前端接口報錯302問題解決辦法

    前端接口報錯302問題解決辦法

    這篇文章主要介紹了前端接口報錯302的問題,并提供了多種解決方法和代碼案例,幫助開發(fā)者更好地應對這一常見問題,需要的朋友可以參考下
    2025-01-01

最新評論

旬邑县| 通渭县| 三原县| 塔河县| 彝良县| 江孜县| 台州市| 昭平县| 巴中市| 固安县| 云林县| 格尔木市| 盐源县| 英吉沙县| 都匀市| 镇沅| 万全县| 嘉峪关市| 镇雄县| 永新县| 中超| 城固县| 昌江| 紫金县| 额济纳旗| 元阳县| 上高县| 喀什市| 城口县| 唐海县| 安乡县| 丰宁| 乐东| 五家渠市| 黔西| 永昌县| 富蕴县| 隆子县| 始兴县| 汽车| 易门县|