今天的主題也是稍微比較細一點的東西,我們在之前的文章中探討過require & module.exports的使用,但其實要輸出變數也可以單純使用exports即可,什麼意思? 看一下下方的範例。
greet.js
exports.greet = function () {
console.log("hi I am Danny")
}
app.js(主程式)
const greet = require('/greet.js')
greet.greet() //hi I am Danny
看到這邊你可能會覺得奇怪,欸 怎麼好像跟前面用module.exports的用法一模一樣?
沒錯,你注意到重點了,在這種情況下使用他們的確是一模一樣的! 首先有個重要的觀念要釐清。
module.exports才是老大
用英文來講的話,就是 it’s the real deal. 而exports只是一個縮寫的用法(short hand),用兩種不同的方式輸出的物件、變數以及函式都會指向同一個記憶體位置,原理就是之前提過的pass by reference,那是不是代表用哪個都沒差? 對,但也不對,我們看一下以下的例子。
greet.js
exports = function () {
console.log("Hello")
}
console.log(exports)
console.log(module.exports);
你認為輸出結果會是什麼? 剛剛有提過他們指向的會是同一個位置嘛! 就算我不知道輸出結果,至少我能肯定他們一定是一樣的! 真的是嗎? 很遺憾的,以下是輸出結果

原因其實相當單純,當你今天將exports設為某個值或是函式,你便打破了pass by reference的結構,讓exports指向一個全新的物件,而這個物件在上方的例子中被設為一個函數,自然輸出的結果就是一個函數了。這是JS中一個比較奇怪的點,也因此為什麼了解pass by value 跟 pass by reference如此重要,最後我們做個簡單的總結。
- 如果沒有特別的偏好,乖乖用module.exports 其實沒讓你多打幾個字
- 當你賦予一個變數值的時候,會讓它指向一個新的記憶體位置,注意,這邊指的是賦予,而不是修改(mutate)