module.exports和exports的區別
- 2022 年 3 月 16 日
- 筆記
module.exports和exports的區別
我們要弄明白module.exports和exports的區別,就要清楚什麼是值類型,什麼是引用類型。值類型是存儲在棧上,引用類型存儲在堆上。引用類型的名字是存儲在棧上的,這個名字指向堆上的一個地址即該引用類型所在的地址。
我們用代碼認識一下引用類型
var p1 = {
name: 'zhangsan',
age: 18
}
var p2 = p1
console.log(p2.name) //打印出zhangsan
此時 var p1 和var p2指向同一個堆地址即兩個存儲在棧上的引用類型名稱 指向同一個引用類型,此時當我門改變p2的屬性值,p1也會跟着改變
var p1 = {
name: 'zhangsan',
age: 18
}
var p2 = p1
p2.age = 19
console.log(p1.age) //打印結果 19
其實此時存儲在棧上的變量名稱p1和p2是指向同一個堆中的對象,當我們改變對象的某個屬相。相當於兩個變量名稱指向的同一個對象改變了。
理解了上面的引用類型改變的原理之後其實就很好理解了。module
和exports
是Node.js
給每個js文件內置的兩個對象。可以通過console.log(module.exports)
和console.log(exports)
打印出來都為一個空對象{}
實際上兩者的關係就如同上面的p1和p2的關係。module.exports和exports是指向同一個堆地址的
module.exports = exports = {}
require
引入的對象本質上是module.exports
。這就產生了一個問題,當 module.exports
和exports
指向的不是同一塊內存時,exports
的內容就會失效。
示例代碼common.js :
module.exports={
sayHello:name=>{
console.log(`hello ${name}`)
}
}
exports.sayGoodbye=name=>{
console.log(`Goodbye ${name}`)
}
示例代碼index.js :
const common =require('./common.js')
common.sayHello('xin')
common.sayGoodbye('xin') //這裡會報錯 common.sayGoodbye is not function
這裡的報錯是因為當執行common.js文件中的module.exports={ …}這段代碼的時候 實際上是給module.exports重新賦值
又因為require
默認引用的是module.exports所指向的對象。所以此時exports的導出依然已經失效。就拋出了common.sayGoodbye is not function
的錯誤
總結:
初始狀態為module.exports = exports ={}
當exports 和module.exports指向的不是同一個堆地址時。exports失效!