我也來爲你們分析分析 node.js 中 exports 和 module.exports 的簡單區別javascript
首先明確一點 module.exports = exports = {},在初始化的時候是這樣的,這裏 exports 做爲 module.exports 的一個輔助工具存在。而 js 的對象是以引用傳值的方式存在的,因此兩者此時指向的是同一地址。java
注意:這裏必定要理解 js 的一些數據類型的特性,像咱們經常使用的數值,字符串,布爾他們都是值傳遞的,而數組,對象都是引用傳遞的node
foo = bar = 10 foo 和 bar 此時指向同一地址 foo = 20 js 新建了一個 20 的常量,並讓 foo 指向它,此時 bar 指向的依然爲 10 bar // 10 foo = bar = {} foo 和 bar 此時指向同一地址 foo.name = "big_cat" 此時 js操做的依然爲 foo 和 bar 指向的對象 bar.name // big_cat //若是 foo = {"name": "other"} // js 新建一個對象 並讓 foo 指向它 foo 已經切斷了和前對象的聯繫 bar.name // big_cat
當你 require 某個模塊文件時,承接上下文的實際上是 module.exports,是他將引入的文件封裝成一個模塊,而後傳遞給你,你就拿到了引用模塊的接口。數組
exports的使用方法工具
/** * person.js */ exports.eat = function(food = '') { console.log("person eats " + food); } exports.drink = function(drinking = '') { console.log("person drinks " + drinking); }
exports 在初始化時做爲 module.exports 的一個副本工具,如上所示增長成員,就等同於給 module.exports 增長成員,順理而然的 require 使用 module.exports 做爲表明文件模塊時也能夠正常使用ui
but,若是你這樣用spa
exports = { eat:function(food) { console.log("person eats " + food); }, drink: function(drinking) { console.log("person drinks " + drinking); } }
要知道,你這裏是給 exports 從新初始化並賦值了,他完全的和 module.exports 脫離的關係,他完全的變成了你模塊文件裏的一個變量code
因此若是你這樣寫了還像往常同樣引入文件模塊,調用其上的方法時,就該報錯了,由於 module.exports 的值爲 NULL,exports 已經完全斷絕了與 module.exports 的關係了,他不會把本身的成員交給 module.exports,進而讓你正常引用了,它只是一個普通的變量了。對象
應該這樣寫接口
module.exports = { eat:function(food) { console.log("person eats " + food); }, drink: function(drinking) { console.log("person drinks " + drinking); } }
如上寫法你即可以正常引用模塊文件而後調用對應的方法了,一個經過 require 引入的文件能夠做爲一個 module,而 module.exports 做爲對外的接口,將本身封裝的功能開放出去,供調用者使用
簡單來講
exports 在初始化的時候會被指命爲 module.exports 的輔助工具,承接註冊新的模塊成員,在被模塊被引入時將註冊名單轉交給 module.exports, module.exports 再轉交給你,exports 對你是透明的
可是,若是你從新將 exports 初始化,他就脫離了 module.exports 的管控,因此他不會將你天真的註冊給他的數據上報給 module.exports,因此你便訪問不到你想要的方法。