ES6與CommonJS中如何對(duì)模塊進(jìn)行處理的

本篇文章為大家展示了ES6與CommonJS中如何對(duì)模塊進(jìn)行處理的,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

為北票等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及北票網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)、北票網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

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

為了方便兩種方式的測(cè)試,使用nodejs的環(huán)境進(jìn)行測(cè)試

CommonJS的模塊處理

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

// exportDemo.js
count = 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.js
var {Hello} = require("./exportDemo")
var hello = new Hello();

hello.setName("Blank");
hello.sayHello();

在終端執(zhí)行 node requireDemo.js ,返回結(jié)果為'hello Mr.Blank'

導(dǎo)出的Hello函數(shù)是原函數(shù)的一次拷貝,修改Hello函數(shù)的屬性值不會(huì)對(duì)其他require的地方造成影響

var { Hello, count } = require('./exportDemo')
var hello = new Hello();
// 讓count自增
console.log(hello.getId());
console.log(hello.getId());
// 發(fā)現(xiàn)獲取的count還是原值
console.log(count)

// 真正的count其實(shí)是已經(jīng)改了的
var newHello = new Hello();
console.log(newHello.getId())

var { Hello: newHello, count: newCount } = require('./exportDemo')
console.log(newCount, 'newCount');
// 再次require,取得的newHello和之前require的Hello指向同一個(gè)拷貝
console.log(newHello === Hello)

ES6的模塊處理

nodejs中運(yùn)行ES6風(fēng)格的代碼

nodejs默認(rèn)是不支持ES6的模塊處理方案的。

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

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

與CommonJS模塊處理的區(qū)別

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

// exportDemo.mjs
export let counter = 1;
export function incCounter() {
 counter ++;
}
// importDemo.mjs
import { counter, incCounter } from './exportDemo.mjs'

incCounter();
console.log(counter)		// 打印結(jié)果為2,而不是初始值的1

CommonJS模塊是運(yùn)行時(shí)加載,ES6模塊是編譯時(shí)輸出接口

Nodejs此類的運(yùn)行環(huán)境會(huì)在一個(gè)閉包中運(yùn)行CommonJS模塊代碼

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

ES6 模塊不會(huì)緩存運(yùn)行結(jié)果,而是動(dòng)態(tài)地去被加載的模塊取值,并且變量總是綁定其所在的模塊。

// exportDemo.mjs
export let a = 1;
export const b = 2;
export let obj = {};

// importDemo.mjs
import { a, b } from './exportDemo.mjs'
console.log(a, b)
a = 1 // 報(bào)錯(cuò),TypeError: Assignment to constant variable,export出來的值是一個(gè)只讀引用
obj.x = 1	// 可以改變屬性值

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

有時(shí)候我們會(huì)在代碼發(fā)現(xiàn) export default obj 的用法,那么這個(gè)default是用來干嘛的?

default是ES6引入的與export配套使用的關(guān)鍵字,用來給匿名對(duì)象、匿名函數(shù)設(shè)置默認(rèn)的名字用的

export出來的值必須要有一個(gè)命名,否則從語(yǔ)法層次便會(huì)報(bào)錯(cuò)

讓我們看一下以下幾個(gè)會(huì)報(bào)錯(cuò)的錯(cuò)誤例子

export匿名對(duì)象

export { x: 1 }	// 報(bào)錯(cuò),SyntaxError:Unexpected token,這是一個(gè)編譯階段的錯(cuò)誤

// 正確寫法
export default { x: 1 }

export匿名函數(shù)

export function() {}	// 報(bào)錯(cuò),SyntaxError: Unexpected token (

// 正確寫法
export default function() {}

循環(huán)引用(recycling loading)

在復(fù)雜的模塊中,可能會(huì)出現(xiàn)模塊間的 互相引用。

commonJS的循環(huán)引用運(yùn)行機(jī)制

// a.js
exports.loaded = false;
var b = require('./b.js')
console.log("b in a is " + JSON.stringify(b))
exports.loaded = true;
console.log("a complete")
// b.js
exports.loaded = false;
var a = require('./a.js')
console.log("a in b is " + JSON.stringify(a))
exports.loaded = true;
console.log("b complete")
// main.js
var 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))

執(zhí)行指令 nodejs main.js

時(shí)序圖下的執(zhí)行步驟分解圖如下所示:

ES6與CommonJS中如何對(duì)模塊進(jìn)行處理的 

ES6的循環(huán)引用運(yùn)行機(jī)制

一個(gè)會(huì)報(bào)錯(cuò)的例子

// a.mjs
import { bar } from './b.mjs'

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

console.log(foo)

export let bar = 'bar from b.mjs'
// main.mjs
import { foo } from './a.mjs'
import { bar } from './b.mjs'

node main.mjs

時(shí)序圖下的執(zhí)行步驟分解圖如下所示:

ES6與CommonJS中如何對(duì)模塊進(jìn)行處理的

ES6的循環(huán)引用要特別注意變量是否已被聲明,若未被聲明的塊級(jí)作用域變量被其他模塊引用時(shí),會(huì)報(bào)錯(cuò)。

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

// a.mjs
import { bar } from './b.mjs'

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

node main.mjs

返回結(jié)果:

foo from a.mjs
bar from b.mjs

時(shí)序圖下的執(zhí)行步驟分解圖如下所示:

ES6與CommonJS中如何對(duì)模塊進(jìn)行處理的 

上述內(nèi)容就是ES6與CommonJS中如何對(duì)模塊進(jìn)行處理的,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

當(dāng)前題目:ES6與CommonJS中如何對(duì)模塊進(jìn)行處理的
本文地址:http://www.muchs.cn/article2/ijssic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開發(fā)、網(wǎng)站策劃、企業(yè)網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、Google用戶體驗(yàn)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化