(譯)Node.js的模塊-exports和module.exports

原文標題:Node.js Module – exports vs module.exports
原文連接:http://www.hacksparrow.com/node-js-exports-vs-module-exports.htmlhtml

exports 和 module.exports 有什麼區別?

你必定很熟悉 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

相關文章
相關標籤/搜索