溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

CommonJs和Es Module有哪些區(qū)別

發(fā)布時(shí)間:2021-10-08 10:36:20 來(lái)源:億速云 閱讀:255 作者:小新 欄目:web開(kāi)發(fā)

這篇文章主要為大家展示了“CommonJs和Es Module有哪些區(qū)別”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“CommonJs和Es Module有哪些區(qū)別”這篇文章吧。

為什么會(huì)有CommonJs和Es Module呢

我們都知道在早期JavaScript模塊這一概念,都是通過(guò)script標(biāo)簽引入js文件代碼。當(dāng)然這寫(xiě)基本簡(jiǎn)單需求沒(méi)有什么問(wèn)題,但當(dāng)我們的項(xiàng)目越來(lái)越龐大時(shí),我們引入的js文件就會(huì)越多,這時(shí)就會(huì)出現(xiàn)以下問(wèn)題:

  • js文件作用域都是頂層,這會(huì)造成變量污染

  • js文件多,變得不好維護(hù)

  • js文件依賴(lài)問(wèn)題,稍微不注意順序引入錯(cuò),代碼全報(bào)錯(cuò)

為了解決以上問(wèn)題JavaScript社區(qū)出現(xiàn)了CommonJs,CommonJs是一種模塊化的規(guī)范,包括現(xiàn)在的NodeJs里面也采用了部分CommonJs語(yǔ)法在里面。那么在后來(lái)Es6版本正式加入了Es Module模塊,這兩種都是解決上面問(wèn)題,那么都是解決什么問(wèn)題呢。

  • 解決變量污染問(wèn)題,每個(gè)文件都是獨(dú)立的作用域,所以不存在變量污染

  • 解決代碼維護(hù)問(wèn)題,一個(gè)文件里代碼非常清晰

  • 解決文件依賴(lài)問(wèn)題,一個(gè)文件里可以清楚的看到依賴(lài)了那些其它文件

那么我們下面來(lái)一一了解它們的語(yǔ)法及弊端吧

CommonJs 基本語(yǔ)法

導(dǎo)出

CommonJs中使用module.exports導(dǎo)出變量及函數(shù),也可以導(dǎo)出任意類(lèi)型的值,看如下案例。

// 導(dǎo)出一個(gè)對(duì)象
module.exports = {
    name: "蛙人",
    age: 24,
    sex: "male"
}

// 導(dǎo)出任意值
module.exports.name = "蛙人"
module.exports.sex = null
module.exports.age = undefined

直接導(dǎo)出

導(dǎo)出也可以省略module關(guān)鍵字,直接寫(xiě)exports導(dǎo)出也可以,看如下案例。

exports.name = "蛙人"
exports.sex = "male"

注意:如果使用exports導(dǎo)出單個(gè)值之后,就不能在導(dǎo)出一個(gè)對(duì)象值,這只會(huì)修改exports的對(duì)象改變,然而修改無(wú)效,最終導(dǎo)出還是name,和sex,因?yàn)樽罱K的導(dǎo)出是由module.exports決定的。

exports.name = "蛙人"
exports.sex = "male"
exports = {
    name: "蛙人"
}

上面example中,這種情況會(huì)改變對(duì)象的引用值則導(dǎo)出無(wú)效,所以最后導(dǎo)出的還是name,sex

混合導(dǎo)出

混合導(dǎo)出,exportsmodule.exports可以同時(shí)使用,不會(huì)存在問(wèn)題。

exports.name = "蛙人"
module.exports.age = 24

導(dǎo)入

CommonJs中使用require語(yǔ)法可以導(dǎo)入,如果想要單個(gè)的值,可以通過(guò)解構(gòu)對(duì)象來(lái)獲取。

// index.js
module.exports.name = "蛙人"
module.exports.age = 24

let data = require("./index.js")
console.log(data) // { name: "蛙人", age: 24 }

重復(fù)導(dǎo)入

不管是CommonJs還是Es Module都不會(huì)重復(fù)導(dǎo)入,就是只要該文件內(nèi)加載過(guò)一次這個(gè)文件了,我再次導(dǎo)入一次是不會(huì)生效的。

let data = require("./index.js")
let data = require("./index.js") // 不會(huì)在執(zhí)行了

動(dòng)態(tài)導(dǎo)入

CommonJs支持動(dòng)態(tài)導(dǎo)入,什么意思呢,就是可以在語(yǔ)句中,使用require語(yǔ)法,來(lái)看如下案例。

let lists = ["./index.js", "./config.js"]
lists.forEach((url) => require(url)) // 動(dòng)態(tài)導(dǎo)入

if (lists.length) {
    require(lists[0]) // 動(dòng)態(tài)導(dǎo)入
}

導(dǎo)入值的變化

CommonJs導(dǎo)入的值是拷貝的,所以可以修改拷貝值,但這會(huì)引起變量污染,一不小心就重名。

// index.js
let num = 0;
module.exports = {
    num,
    add() {
       ++ num 
    }
}

let { num, add } = require("./index.js")
console.log(num) // 0
add()
console.log(num) // 0
num = 10

上面example中,可以看到exports導(dǎo)出的值是值的拷貝,更改完++ num值沒(méi)有發(fā)生變化,并且導(dǎo)入的num的值我們也可以進(jìn)行修改

總結(jié)

CommonJs解決了變量污染,文件依賴(lài)等問(wèn)題,上面我們也介紹了它的基本語(yǔ)法,它可以動(dòng)態(tài)導(dǎo)入(代碼發(fā)生在運(yùn)行時(shí)),不可以重復(fù)導(dǎo)入。

Es Module 基本語(yǔ)法

導(dǎo)出

Es Module中導(dǎo)出分為兩種,單個(gè)導(dǎo)出(export)、默認(rèn)導(dǎo)出(export default),單個(gè)導(dǎo)出在導(dǎo)入時(shí)不像CommonJs一樣直接把值全部導(dǎo)入進(jìn)來(lái)了,Es Module中可以導(dǎo)入我想要的值。那么默認(rèn)導(dǎo)出就是全部直接導(dǎo)入進(jìn)來(lái),當(dāng)然Es Module中也可以導(dǎo)出任意類(lèi)型的值。

// 導(dǎo)出變量
export const name = "蛙人"
export const age = 24

// 導(dǎo)出函數(shù)也可以
export function fn() {}
export const test = () => {}


// 如果有多個(gè)的話
const name = "蛙人"
const sex = "male"
export { name, sex }

混合導(dǎo)出

可以使用exportexport default同時(shí)使用并且互不影響,只需要在導(dǎo)入時(shí)地方注意,如果文件里有混合導(dǎo)入,則必須先導(dǎo)入默認(rèn)導(dǎo)出的,在導(dǎo)入單個(gè)導(dǎo)入的值。

export const name = "蛙人"
export const age = 24

export default {
    fn() {},
    msg: "hello 蛙人"
}

導(dǎo)入

Es Module使用的是import語(yǔ)法進(jìn)行導(dǎo)入。如果要單個(gè)導(dǎo)入則必須使用花括號(hào){} ,注意:這里的花括號(hào)跟解構(gòu)不一樣。

// index,js
export const name = "蛙人"
export const age = 24

import { name, age } from './index.js'
console.log(name, age) // "蛙人" 24

// 如果里面全是單個(gè)導(dǎo)出,我們就想全部直接導(dǎo)入則可以這樣寫(xiě)
import * as all from './index.js'
console.log(all) // {name: "蛙人", age: 24}

混合導(dǎo)入

混合導(dǎo)入,則該文件內(nèi)用到混合導(dǎo)入,import語(yǔ)句必須先是默認(rèn)導(dǎo)出,后面再是單個(gè)導(dǎo)出,順序一定要正確否則報(bào)錯(cuò)。

// index,js
export const name = "蛙人"
export const age = 24
export default {
    msg: "蛙人"
}

import msg, { name, age } from './index.js'
console.log(msg) // { msg: "蛙人" }

上面example中,如果導(dǎo)入的名稱(chēng)不想跟原本地名稱(chēng)一樣,則可以起別名。

// index,js
export const name = "蛙人"
export const age = 24
export default {
    msg: "蛙人"
}

import { default as all,  name, age } from './index.js'
console.log(all) // { msg: "蛙人" }

導(dǎo)入值的變化

export導(dǎo)出的值是值的引用,并且內(nèi)部有映射關(guān)系,這是export關(guān)鍵字的作用。而且導(dǎo)入的值,不能進(jìn)行修改也就是只讀狀態(tài)。

// index.js
export let num = 0;
export function add() {
    ++ num
}

import { num, add } from "./index.js"
console.log(num) // 0
add()
console.log(num) // 1
num = 10 // 拋出錯(cuò)誤

Es Module是靜態(tài)

就是Es Module語(yǔ)句``import只能聲明在該文件的最頂部,不能動(dòng)態(tài)加載語(yǔ)句,Es Module`語(yǔ)句運(yùn)行在代碼編譯時(shí)。

if (true) {
	import xxx from 'XXX' // 報(bào)錯(cuò)
}

總結(jié)

Es Module也是解決了變量污染問(wèn)題,依賴(lài)順序問(wèn)題,Es Module語(yǔ)法也是更加靈活,導(dǎo)出值也都是導(dǎo)出的引用,導(dǎo)出變量是可讀狀態(tài),這加強(qiáng)了代碼可讀性。

CommonJs和Es Module的區(qū)別

CommonJs

  • CommonJs可以動(dòng)態(tài)加載語(yǔ)句,代碼發(fā)生在運(yùn)行時(shí)

  • CommonJs混合導(dǎo)出,還是一種語(yǔ)法,只不過(guò)不用聲明前面對(duì)象而已,當(dāng)我導(dǎo)出引用對(duì)象時(shí)之前的導(dǎo)出就被覆蓋了

  • CommonJs導(dǎo)出值是拷貝,可以修改導(dǎo)出的值,這在代碼出錯(cuò)時(shí),不好排查引起變量污染

Es Module

  • Es Module是靜態(tài)的,不可以動(dòng)態(tài)加載語(yǔ)句,只能聲明在該文件的最頂部,代碼發(fā)生在編譯時(shí)

  • Es Module混合導(dǎo)出,單個(gè)導(dǎo)出,默認(rèn)導(dǎo)出,完全互不影響

  • Es Module導(dǎo)出是引用值之前都存在映射關(guān)系,并且值都是可讀的,不能修改

以上是“CommonJs和Es Module有哪些區(qū)別”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI