2014-07-08 83 views
2

我剛剛瀏覽了nodejs源文件並注意到不同模塊導出方式之間的差異。例如,一些模塊導出對象與原型繼承樣式:nodejs模塊及其導出之間的差異

Thing = function() { 
    constructor stuff 
} 

Thing.prototype.jump() { 
    jump stuff 
} 

exports = Thing 

凡爲其他模塊將直接附加功能,以出口:

exports.spectacles = function() { 
    spectacle stuff 
} 

對我來說,似乎他們將實現類似的目標,但它們明顯不同。我相信第一個例子描述了類似的東西,而第二個例子簡單地提供了靜態方法。

這兩種方法之間的根本區別是什麼?它們是如何被恰當地描述的?它們之間的優點和缺點是什麼?

回答

3

您指出的差異主要是基於味道的。這與人們喜歡如何構建物體非常相關。

JavaScript有不同的方式來構建對象很多的,這裏是另一個例子:

exports.stuff = { 
    f1: function() ... 
    foobar: function() ... 
} 

舉例來說,我更喜歡包裹一切與函數強制使用嚴格和仿真靜態變量:

(function() { 
    "use strict"; 
    var staticVariable; 

    function MyObject() { 
    ... 
    }; 

    exports.MyObject = MyObject; 
})(); 

近距離投票+1。這個問題很主觀。

4

請嘗試從另一個角度查看此模塊:需要您的模塊。

Node中的每個文件都是一個模塊。每個模塊都有一個全局變量module,它的屬性爲exports。無論你放在那個exports屬性將作爲模塊的出口。

原始

即,一個布爾值,數字或字符串將工作:

module.exports = 3; 

當你需要該文件,你會得到'3'。

var myModule = require('./my-module'); 
console.log(myModule); // <== 3 

但由於一切都在JavaScript是一個對象,那麼你可以調用方法,甚至原始的道具:

console.log(myModule.toString()); // <== "3" 

功能

您還可以導出的函數。

module.exports = function() { 
    console.log('3 more'); 
}; 

出口將是一個功能:

var myModule = require('./my-module'); 
myModule(); // <== '3 more' 

當然,功能也是一個對象,所以你必須對方法太嘗試。

console.log(myModule.toString()); 
// You get: 'function(){\n console.log(\'3 more\');\n }' 

對象

然後你就可以用幾個出口的那些東西的對象:

module.exports = { 
    prop: 3, 
    method: function() { 
     console.log('Not 3 this time.'); 
    } 
}; 

當你需要這個模塊,你將有一個對象 - 一個屬性的對象prop和方法method

var myModule = require('./my-module'); 
console.log(myModule.prop); // <== 3 
myModule.method();   // <== 'Not 3 this time' 

所以你得到的模式?無論你在module.exports中放置什麼,都可以在另一端獲得。正如我所說,這是一個觀點問題。

默認

即使你不出口任何東西(即需要一個空文件),你有一個出口。

需要一個空文件(它有壽

var myModule = require('./my-module'); 
console.log(myModule); // <== {} 

這告訴你的是,默認的出口是一個空物體存在。


這是它變得有趣。

如果默認module.exports = {},那麼如果我們簡單地附加到它,我們可以添加道具:

因此,當Node首次獲取您的模塊(文件)時,它是{}。我們可以簡單地附上道具。

module.exports.prop = 3; 
module.exports.method = function() { console.log('I am out of ideas for placeholders, I should use kitten');} 

爲什麼它沒有module關鍵字工作?

現在,爲什麼這個工作沒有module關鍵字? IE瀏覽器。只是:

exports.prop = 3; 
exports.method = function() {}; 

因爲當Node.js開始工作您的文件時,它會將輸出別名到module.exports。 但要小心,您可以覆蓋此!

這是什麼意思?這幾乎就像您在文件的開頭寫入var exports = module.exports一樣。

所以你可以只使用exports語法,但我不喜歡。爲什麼?因爲你可以犯一個錯誤,並且覆蓋exports var。你會更加註意module.exports。 (還有其他原因,這一個是我所學到的第一個和最好的懷念。)

例1:

exports.prop = false; 

// later in module 
module.exports = myObj; // see? overriden. 

例2:

var exports = {}; // see? Overridden default module.exports. 
exports.prop = 4; 

exports.method = function(){ 
    console.log('3 more'); 
}; 

所以,當你需要稍後:

var myModule = require('./my-module'); 
console.log(myModule); // <== {} 

我希望這會有所幫助。

+1

謝謝Zlatko,非常全面。 – oorst