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是指向同一個堆中的對象,當我們改變對象的某個屬相。相當於兩個變量名稱指向的同一個對象改變了。

理解了上面的引用類型改變的原理之後其實就很好理解了。moduleexportsNode.js給每個js文件內置的兩個對象。可以通過console.log(module.exports)console.log(exports)打印出來都為一個空對象{}

實際上兩者的關係就如同上面的p1和p2的關係。module.exports和exports是指向同一個堆地址的

module.exports = exports = {}

require引入的對象本質上是module.exports。這就產生了一個問題,當 module.exportsexports指向的不是同一塊內存時,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失效!