国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

ES6與CommonJS中的模塊處理的區別

2019-11-19 13:39:23
字體:
來源:轉載
供稿:網友

ES6和CommonJS都有自己的一套處理模塊化代碼的措施,即JS文件之間的相互引用。

為了方便兩種方式的測試,使用nodejs的環境進行測試

CommonJS的模塊處理

使用require來引入其他模塊的代碼,使用module.exports來引出

// exportDemo.jscount = 1;module.exports.count = count;module.exports.Hello = function() { var name; this.setName = function(newName) { name = newName; } this.sayHello = function() { console.log("hello Mr." + name); } this.getId = function() { return count++ }}
// requireDemo.jsvar {Hello} = require("./exportDemo")var hello = new Hello();hello.setName("Blank");hello.sayHello();

在終端執行 node requireDemo.js ,返回結果為'hello Mr.Blank'

導出的Hello函數是原函數的一次拷貝,修改Hello函數的屬性值不會對其他require的地方造成影響

var { Hello, count } = require('./exportDemo')var hello = new Hello();// 讓count自增console.log(hello.getId());console.log(hello.getId());// 發現獲取的count還是原值console.log(count)// 真正的count其實是已經改了的var newHello = new Hello();console.log(newHello.getId())var { Hello: newHello, count: newCount } = require('./exportDemo')console.log(newCount, 'newCount');// 再次require,取得的newHello和之前require的Hello指向同一個拷貝console.log(newHello === Hello) 

ES6的模塊處理

nodejs中運行ES6風格的代碼

nodejs默認是不支持ES6的模塊處理方案的。

但是在8.5.0之后,ES6代碼的文件格式定為mjs后,可使用 node --experimental-modules xxx.mjs 運行。

// exportDemo.mjsexport let a = 1;
// importDemo.mjsimport {a} from './exportDemo.mjs'console.log(a)

與CommonJS模塊處理的區別

CommonJS 模塊輸出的是一個值的拷貝(已在上一章驗證),ES6 模塊輸出的是值的引用。

// exportDemo.mjsexport let counter = 1;export function incCounter() { counter ++;}
// importDemo.mjsimport { counter, incCounter } from './exportDemo.mjs'incCounter();console.log(counter)		// 打印結果為2,而不是初始值的1

CommonJS模塊是運行時加載,ES6模塊是編譯時輸出接口

Nodejs此類的運行環境會在一個閉包中運行CommonJS模塊代碼

(function(exports, require, module, __filename, __dirname) {// Module code actually lives in here});

ES6 模塊不會緩存運行結果,而是動態地去被加載的模塊取值,并且變量總是綁定其所在的模塊。

// exportDemo.mjsexport let a = 1;export const b = 2;export let obj = {};// importDemo.mjsimport { a, b } from './exportDemo.mjs'console.log(a, b)a = 1 // 報錯,TypeError: Assignment to constant variable,export出來的值是一個只讀引用obj.x = 1	// 可以改變屬性值

在ES6模塊中我們更多地要去考慮語法的問題 export default

有時候我們會在代碼發現 export default obj 的用法,那么這個default是用來干嘛的?

default是ES6引入的與export配套使用的關鍵字,用來給匿名對象、匿名函數設置默認的名字用的

export出來的值必須要有一個命名,否則從語法層次便會報錯

讓我們看一下以下幾個會報錯的錯誤例子

export匿名對象

export { x: 1 }	// 報錯,SyntaxError:Unexpected token,這是一個編譯階段的錯誤// 正確寫法export default { x: 1 }

export匿名函數

export function() {}	// 報錯,SyntaxError: Unexpected token (// 正確寫法export default function() {}

循環引用(recycling loading)

在復雜的模塊中,可能會出現模塊間的 互相引用

commonJS的循環引用運行機制

// a.jsexports.loaded = false;var b = require('./b.js')console.log("b in a is " + JSON.stringify(b))exports.loaded = true;console.log("a complete")
// b.jsexports.loaded = false;var a = require('./a.js')console.log("a in b is " + JSON.stringify(a))exports.loaded = true;console.log("b complete")
// main.jsvar a = require('./a.js')var b = require('./b.js')console.log("a in main is" + JSON.stringify(a))console.log("b in main is" + JSON.stringify(b))

執行指令 nodejs main.js

時序圖下的執行步驟分解圖如下所示:

 

ES6的循環引用運行機制

一個會報錯的例子

// a.mjsimport { bar } from './b.mjs'console.log(bar);export let foo = 'foo from a.mjs'
// b.mjsimport { foo } from './a.mjs'console.log(foo)export let bar = 'bar from b.mjs'
// main.mjsimport { foo } from './a.mjs'import { bar } from './b.mjs'

node main.mjs

時序圖下的執行步驟分解圖如下所示:

ES6的循環引用要特別注意變量是否已被聲明,若未被聲明的塊級作用域變量被其他模塊引用時,會報錯。

改進方案:循環引用中盡量去export可以提前確定的值(例如函數),其實我們總是希望去 引用模塊執行完全后最終確定的變量 。

// a.mjsimport { bar } from './b.mjs'console.log(bar());export function foo() { return 'foo from a.mjs'}
// b.mjsimport { foo } from './a.mjs'console.log(foo());export function bar() { return 'bar from b.mjs'}
// main.mjsimport { foo } from './a.mjs'import { bar } from './b.mjs'

node main.mjs

返回結果:

foo from a.mjs
bar from b.mjs

時序圖下的執行步驟分解圖如下所示:

 

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 措勤县| 汉沽区| 桃园县| 南郑县| 辽宁省| 库车县| 泗洪县| 嘉黎县| 齐齐哈尔市| 湘乡市| 清涧县| 龙陵县| 尼勒克县| 霞浦县| 庆安县| 洪洞县| 台湾省| 祥云县| 莱州市| 前郭尔| 东源县| 右玉县| 当阳市| 甘谷县| 敖汉旗| 建湖县| 衡山县| 蚌埠市| 青州市| 赤峰市| 敦煌市| 长汀县| 庆安县| 刚察县| 汝阳县| 抚宁县| 偏关县| 遂平县| 通山县| 修水县| 修水县|