徹底搞懂Node.js中exports與module.exports的區別
先看個例子 A:
let a={name:"chen"}
let b= a //b{name:"chen"}
b 淺拷貝了 a,可以說 b 是 a 的引用,因為它們指向了同一個記憶體地址,它們相互影響。但是!當 b=function bb(){xxx} 後,b就不指向 a 的記憶體地址了,也就是說,b 不再是a 的引用了,從這之後,b的改變不會影響a,a的改變(a 永遠是一個物件)也不會影響b
exports:
(1)它最初是一個可以新增屬性的空物件。
(2)它是 module.exports 的全域性引用。
(3)如例子 A 所說,當用其他物件、函式或變數給 exports 賦值,那麼 exports 就不再是 module.exports 的引用,換句話說,會導不出來所需要的函式、變數,導致報錯。
如例子 B:
currency.js:
function oneToTwo() {
console.log("222")
}
function oneToThree() {
console.log("333")
}
//這裡將一個函式方法賦值給 exports,
//導致 exports 不再是 module.exports 的引用
exports=oneToTwo
testCurrency.js:
let Currency=require("./currency")
//因為匯出的是 module.exports 而不是 export,
//而不再是 module.exports 引用的 exports 沒有改變 module.exports 的值,
//所以 module.exports 的值仍為初始值 {}
console.log(Currency) // {}
module.exports:
(1)程式匯出的永遠是 module.exports
(2)如果你建立了 既有 exports 又有 module.exports 的模組,那它會返回 module.exports
(3)如果 exports 不再是 module.exports 的引用,使用如下方法,重新保持兩者的連線
module.exports=exports=oneToTwo
或者
exports=module.exports=oneToTwo
注意:當你在 currency.js(上面提到的檔案)寫
exports.oneToTwo=oneToTwo
的時候,這個 exports 不是 exports,不是做 module.exports 引用的那個 exports,而是 module.exports,這個 exports.oneToTwo 是 module.exports.oneToTwo 的簡寫。
是不是很搞,很煩?我也覺得很搞,那麼問題來了:
為什麼要拿一個 exports 來做 module.exports 的引用?而不是直接使用 module.exports ?
我現在也還未明白,看了這篇博文(https://cnodejs.org/topic/52308842101e574521c16e06),原話是說「其實,當我們瞭解到原理後,不難明白這樣的寫法有點冗餘,其實是為了保證,模組的初始化環境是乾淨的。同時也方便我們,即使改變了 module.exports 指向的物件後,依然能沿用 exports的特性」
最後用官方的一句話,簡述兩者區別:
If you want the root of your module’s export to be a function (such as a constructor) or if you want to export a complete object in one assignment instead of building it one property at a time, assign it to module.exports instead of exports.
如果希望模組匯出的是其他物件、函式或變數,那麼用 module.exports 而不是 exports
歡迎關注本公眾號:
(完)
相關文章
- exports 和 module.exports 的區別Export
- 一文搞懂exports和module.exports的關係和區別Export
- Nodejs中exports和module.exports與ES6中的export default 和 export 區別NodeJSExport
- Node.js : exports と module.exports の違いNode.jsExport
- module.exports、exports 、export default之間的差異區別及與require、import的使用ExportUIImport
- 淺析Node模組中module.exports與exports的關係Export
- exports和module.exportsExport
- 徹底搞懂Python 中的 import 與 from importPythonImport
- 徹底搞懂JavaScript中的繼承JavaScript繼承
- 徹底搞懂Python中的類Python
- 徹底搞懂 RxJava — 中級篇RxJava
- module.exports與export那些事兒Export
- 徹底搞懂徹底搞懂事件驅動模型 - Reactor事件模型React
- 徹底搞懂 RxJavaRxJava
- JavaScript中的export、export default、exports和module.exports(export、export default、exports使用詳細)JavaScriptExport
- 6.exports、module.exports、export、export defalutExport
- module.exports 、 exports 和 export 、 export default 、 importExportImport
- Node中Exports與module.export的使用與區別Export
- 徹底搞懂 MySQL 事務的隔離級別MySql
- 徹底理解Node.js中的BufferNode.js
- 深入理解Node.js 程式與執行緒(8000長文徹底搞懂)Node.js執行緒
- 徹底搞懂js裡的__proto__和prototype到底有什麼區別?JS
- Java 原始碼出發徹底搞懂String與StringBuffer和StringBuilder的區別Java原始碼UI
- 徹底搞懂https原理HTTP
- 徹底搞懂JavaScript作用域JavaScript
- 徹底搞懂Bean載入Bean
- 徹底搞懂 Git-RebaseGit
- 徹底搞懂同步非同步與阻塞非阻塞非同步
- 幫你徹底搞懂JS中的prototype、__proto__與constructor(圖解)JSStruct圖解
- 一文徹底搞懂JS前端5大模組化規範及其區別JS前端
- 深入JavaScript系列(四):徹底搞懂thisJavaScript
- 徹底搞懂 Channel 實現原理
- 徹底搞懂 RxJava — 基礎篇RxJava
- 徹底搞懂 RxJava — 高階篇RxJava
- exports、module.exports 和 export、export default 到底是咋回事Export
- java9 opens與exports的區別JavaExport
- 幫你徹底搞懂JS中的prototype、__proto__與constructor(圖解)(轉)JSStruct圖解
- 徹底搞懂Scrapy的中介軟體(三)