JS中ESModule和commonjs介紹及使用區(qū)別
ES Module
導(dǎo)出
僅導(dǎo)出
- named exports: 命名導(dǎo)出,每次可以導(dǎo)出一個或者多個。
- default exports: 默認(rèn)導(dǎo)出,每次只能存在一個。
以上兩者可以混合導(dǎo)出:
// 命名導(dǎo)出
export const b = 'b'
// 默認(rèn)導(dǎo)出
export default {
a: 1
};
const c = 'c'
export { c }
// 以上內(nèi)容會合并導(dǎo)出,即導(dǎo)出為: {b:'b', c:'c', default: {a:1}}更多示例可以直接去看mdn
重導(dǎo)出(re-exporting / aggregating)
算是一個導(dǎo)入再導(dǎo)出的一個語法糖吧。
export {
default as function1,
function2,
} from 'bar.js';
// 等價(jià)于
import { default as function1, function2 } from 'bar.js';
export { function1, function2 };然而這種語法是會報(bào)錯的:
export DefaultExport from 'bar.js'; // Invalid
正確的語法應(yīng)該是:
export { default as DefaultExport } from 'bar.js'; // valid我猜是因?yàn)閑xport 本身支持的export xxx這種語法必須是要導(dǎo)出一個對象,然而import xxx可能是任意類型,兩者沖突了,所以從編譯層面就不讓這種語法生效會更好。
嵌入式腳本
嵌入式腳本不可以使用export。
引入
語法
- import all exports:
import * as allVar,所有導(dǎo)出內(nèi)容,包含命名導(dǎo)出及默認(rèn)導(dǎo)出。allVar會是一個對象,默認(rèn)導(dǎo)出會作為allVar的key名為default對應(yīng)的值。 - import named exports:
import {var1, var2},引入命名導(dǎo)出的部分。沒找到,對應(yīng)的值就為undefined。個人覺得可以看做是"import all exports"的解構(gòu)語法。 - import default exports:
import defaultVar,引入默認(rèn)導(dǎo)出的部分。 - import side effects:
import "xxx./js",僅運(yùn)行這個js,可能是為了獲取其副作用。
// test.js
export const b = 'b' // 命名導(dǎo)出
export default { // 默認(rèn)導(dǎo)出
a: 1
};
// index.js
import { b, default as _defaultModule } from './test.js'
import defaultModule from './test.js'
import * as allModule from './test.js'
console.log('name export', b) // 'b'
console.log('default export', defaultModule) // {a:1}
console.log(_defaultModule === defaultModule) // true
console.log('all export', allModule) // {b:'b', default: {a:1}}一個之前老記錯的case
// test.js
export default { // 默認(rèn)導(dǎo)出
a: 1
};
// index.js
import { a } from './test.js'
console.log('name export', a) // undefined
// index.js
import defaultModule from './test.js'
import * as allModule from './test.js'
console.log('default export', defaultModule) // {a:1}
console.log('all export', allModule) // {default: {a:1}}嵌入式腳本
嵌入式腳本引入modules時(shí),需要在script上增加 type="module"。
特點(diǎn)
live bindings:
- 通過export在mdn上的解釋,export導(dǎo)出的是live bindings,再根據(jù)其他文章綜合判斷,應(yīng)該是引用的意思。即export導(dǎo)出的是引用。
- 模塊內(nèi)的值更新了之后,所有使用export導(dǎo)出值的地方都能使用最新值。
read-only:通過import在mdn上的解釋,import使用的是通過export導(dǎo)出的不可修改的引用。
strict-mode:被引入的模塊都會以嚴(yán)格模式運(yùn)行。
靜態(tài)引入、動態(tài)引入
import x from這種語法有syntactic rigid,需要編譯時(shí)置于頂部且無法做到動態(tài)引入加載。如果需要動態(tài)引入,則需要import ()語法。有趣的是,在mdn上,前者分類到了 Statements & declarations, 后者分類到了 Expressions & operators。這倆是根據(jù)什么分類的呢?
true && import test from "./a.js"; // SyntaxError: import can only be used in import() or import.meta // 這里應(yīng)該是把import當(dāng)成了動態(tài)引入而報(bào)錯
示例:
// a.js
const test = {
a: 1
};
export default test;
// 改動模塊內(nèi)部的值
setTimeout(() => {
test.a = 2;
}, 1000);
// index.js
import test from './index.js'
/* live bindings */
console.log(test) // {a:1}
setTimeout(()=>{
console.log(test) // {a:2}
}, 2000)
/* read-only */
test= { a: 3 } // 報(bào)錯, Error: "test" is read-only.
/* syntactically rigid */
if(true){
import test from './index.js' // 報(bào)錯, SyntaxError: 'import' and 'export' may only appear at the top level
}commonJS
導(dǎo)出
在 Node.js 模塊系統(tǒng)中,每個文件都被視為獨(dú)立的模塊。模塊導(dǎo)入導(dǎo)出實(shí)際是由nodejs的模塊封裝器實(shí)現(xiàn),通過為module.exports分配新的值來實(shí)現(xiàn)導(dǎo)出具體內(nèi)容。
module.exports有個簡寫變量exports,其實(shí)就是個引用復(fù)制。exports作用域只限于模塊文件內(nèi)部。 原理類似于:
// nodejs內(nèi)部
exports = module.exports
console.log(exports, module.exports) // {}, {}
console.log(exports === module.exports) // true注意:nodejs實(shí)際導(dǎo)出的是module.exports,以下幾種經(jīng)典case單獨(dú)看一下:
case1:
// ?使用exports exports.a = xxx console.log(exports === module.exports) // true // ?等價(jià)于 module.exports.a = xxx
case2:
// ?這么寫可以導(dǎo)出,最終導(dǎo)出的是{a:'1'}
module.exports = {a:'1'}
console.log(exports, module.exports) // {}, {a:'1'}
console.log(exports === module.exports) // false
// ?不會將{a:'1'}導(dǎo)出,最終導(dǎo)出的是{}
exports = {a:'1'}
console.log(exports, module.exports) // {a:'1'}, {}
console.log(exports === module.exports) // false引入
通過require語法引入:
// a是test.js里module.exports導(dǎo)出的部分
const a = require('./test.js')原理偽代碼:
function require(/* ... */) {
const module = { exports: {} };
((module, exports) => {
// Module code here. In this example, define a function.
function someFunc() {}
exports = someFunc;
// At this point, exports is no longer a shortcut to module.exports, and
// this module will still export an empty default object.
module.exports = someFunc;
// At this point, the module will now export someFunc, instead of the
// default object.
})(module, module.exports);
return module.exports;
}特點(diǎn)
值拷貝
// test.js
let test = {a:'1'}
setTimeout(()=>{
test = {a:'2'}
},1000)
module.exports = test
// index.js
const test1 = require('./test.js')
console.log(test1) // {a:1}
setTimeout(()=>{
console.log(test1) // {a:1}
},2000)ES Module和 commonJS區(qū)別
語法:
exports、module.exports和require 是Node.js模塊系統(tǒng)關(guān)鍵字。
export、export default和import 則是ES6模塊系統(tǒng)的關(guān)鍵字:
原理:
exports、module.exports導(dǎo)出的模塊為值復(fù)制。
export、export default為引用復(fù)制。
時(shí)機(jī):
ES Module靜態(tài)加載是編譯時(shí)確定,ES Module動態(tài)加載是運(yùn)行時(shí)確定。
CommonJS是運(yùn)行時(shí)確定。
到此這篇關(guān)于JS中ESModule和commonjs介紹及使用區(qū)別的文章就介紹到這了,更多相關(guān)JS ESModule和commonjs 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js+html實(shí)現(xiàn)網(wǎng)頁五子棋
這篇文章主要為大家詳細(xì)介紹了js+html實(shí)現(xiàn)網(wǎng)頁五子棋,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
微信小程序下拉加載和上拉刷新兩種實(shí)現(xiàn)方法詳解
這篇文章主要介紹了微信小程序下拉加載和上拉刷新兩種實(shí)現(xiàn)方法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
Js類的靜態(tài)方法與實(shí)例方法區(qū)分及jQuery拓展的兩種方法
這篇文章主要介紹了Js類的靜態(tài)方法與實(shí)例方法區(qū)分及jQuery拓展的兩種方法 的相關(guān)資料,對靜態(tài)方法(Static)和實(shí)例方法(非Static)不太理解的朋友可以一起學(xué)習(xí)下2016-06-06
跟我學(xué)習(xí)javascript的call(),apply(),bind()與回調(diào)
跟我學(xué)習(xí)javascript的call(),apply(),bind()與回調(diào),感興趣的小伙伴們可以參考一下2015-11-11
使用layui實(shí)現(xiàn)樹形結(jié)構(gòu)的方法
今天小編就為大家分享一篇使用layui實(shí)現(xiàn)樹形結(jié)構(gòu)的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
js和jquery判斷數(shù)據(jù)類型的4種方法總結(jié)
這篇文章主要給大家介紹了關(guān)于js和jquery判斷數(shù)據(jù)類型的4種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08

