1. 程式人生 > 其它 >module.exports和exports的區別

module.exports和exports的區別

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失效!