原文標題:Node.js Module – exports vs module.exports
原文連接:http://www.hacksparrow.com/node-js-exports-vs-module-exports.htmlhtml
你必定很熟悉 Node.js 模塊中的用來在你的模塊中建立函數的 exports 對象,就像下面這樣。node
建立一個叫作rocker.js的文件:數組
exports.name = function() { console.log('My name is Lemmy Kilmister'); };
而後能夠在另一個文件中調用 rocker.js :函數
var rocker = require('./rocker.js'); rocker.name(); // 'My name is Lemmy Kilmister'
可是,module.exports 到底什麼?它是合法的嗎?ui
使人吃驚的是:module.exports 是真實存在的。exports 只不過是 module.exports 的幫手而已。你的模塊直接返回返回 module.exports 給調用者,而不是 exports 。全部的 exports 作的工做其實是收集屬性,若是 module.exports 當前沒有任何屬性,exports便將收集到的屬性添加到 module.exports 上。若是 module.exports
已經存在若干屬性,因此 exports 上的屬性都會被忽略。this
修改 rocker.js 文件:spa
module.exports = 'ROCK IT!'; exports.name = function() { console.log('My name is Lemmy Kilmister'); };
在另外一個文件中調用 rocker.js:翻譯
var rocker = require('./rocker.js'); rocker.name(); // TypeError: Object ROCK IT! has no method 'name'
上述例子中的 rocker 模塊徹底將 exports.name 忽略了,只返回了一個 String 字符串:'ROCK IT!' 。 從這個例子你大概明白了:你的模塊並不必定老是一個模塊的實例(module instance),它能夠是任何合法的 JavaScript 對象——boolean, number, date, JSON, string, function, array 和其餘的。你的模塊能夠是任何你設置的 module.exports 的值。若是你沒有明確地爲 module.exports 設置任何值,那麼 exports 中的屬性會自動添加到 module.exports 中,而後並返回它。code
在這種狀況下,你的模塊時一個類:htm
module.exports = function(name, age) { this.name = name; this.age = age; this.about = function() { console.log(this.name +' is '+ this.age +' years old'); }; };
而你能夠像這樣使用:
var Rocker = require('./rocker.js'); var r = new Rocker('Ozzy', 62); r.about(); // Ozzy is 62 years old
在這時候你的模塊是一個數組:
module.exports = [ 'Lemmy Kilmister', 'Ozzy Osbourne', 'Ronnie James Dio', 'Steven Tyler', 'Mick Jagger' ];
而你能夠這樣使用:
var rocker = require('./rocker.js'); console.log('Rockin in heaven: ' + rocker[2]); //Rockin in heaven: Ronnie James Dio
如今你應該明白了點什麼——若是你想讓你的模塊返回一個特殊的對象類型,好比構造函數,那麼你得使用 module.exports ;若是你只想模塊做爲一個典型的模塊實例(module instance),那麼就用exports。
把屬性添加到 module.exports 中和添加到 exports 中的結果是同樣的。好比像這樣:
module.exports.name = function() { console.log('My name is Lemmy Kilmister'); };
其實和下面的是同樣的:
exports.name = function() { console.log('My name is Lemmy Kilmister'); };
可是要注意,他們不是同一個東西。就像以前說的同樣,exports 只不過是 module.exports 的幫手而已。話雖如此,exports 仍是推薦的對象,除非你想把你模塊的對象類型從傳統的模塊實例(module instance)修改成其餘的。
只要你沒有使用賦值運算重寫 module.exports 對象,任何添加到 module.exports 和 exports 的屬性都可以在 require 模塊中。
好比這是你的模塊中的內容:
module.exports.age = 68; exports.name = 'Lemmy Kilmister';
下面的代碼能夠很好的工做:
var rocker = require('./rocker.js'); console.log('%s is %s', rocker.name, rocker.age); // Lemmy Kilmister is 68
可是,若是你在你的模塊中重寫了 module.exports 中的任何地方,代碼便會出錯:
module.exports = 'LOL'; module.exports.age = 68; exports.name = 'Lemmy Kilmister';
或者這樣:
module.exports.age = 68; exports.name = 'Lemmy Kilmister'; module.exports = 'WTF';
順序沒有關係,rocker.age 和 rocker.name 將顯示爲 undefined。
而且注意:只是由於 module.exports 和 exports 都能輸出模塊,並不意味這你能夠組合使用。個人建議是,堅持使用 exports.*,明白module.exports
我但願這篇文章能幫助你理解exports和module.exports之間的不一樣,而且能進一步的理解模塊在Node.js中是怎麼工做的。
(完)
翻譯水平有待提升,所翻譯的博文並非按照原文一句一句翻譯,而是添加了本身對文章的理解。若有不正之處,歡迎指正!
我的筆記,僅供參考。
參考:
http://www.hacksparrow.com/node-js-exports-vs-module-exports.html