2014-02-26 113 views
1

樣式1:對象與構造/原型在node.js中編碼風格

function DB(url) { 
    this.url = url; 
} 

DB.prototype.info = function (callback) { 
    http.get(this.url + '/info', callback); 
}; 

樣式2:瓶蓋

function DB(url) { 
    return { info: async.apply(http.get, url + '/info') }; 
} 

這僅僅是一個例子,假設有涉及更多的原型方法和私有方法。

我已閱讀的帖子OneTwo閉包風格比nodej更優先於另一個。請幫我澄清爲什麼在nodejs中使用this.something語法不好。

你可以給出你的意見哪個更好,但我主要是需要知道什麼是在nodejs中使用每種風格的優點和缺點。

回答

0

節點遵循JavaScript標準。所以任何javascript編碼風格對於node.js都是合適的編碼風格。但以下鏈接可能會給你node.js編碼風格的縮寫。

http://nodeguide.com/style.html

http://innofied.com/javascript-coding-standards-follow/

+0

但這兩個鏈接都沒有提到我提到的特定風格。 N其次,我認爲你錯了,說節點遵循JavaScript風格,因爲NODE是一個不同的平臺,它可以有不同的約定和風格,在瀏覽器中不是典型的JavaScript。 –

+0

對於任何平臺,JavaScript的編碼標準都應該相同。它可能取決於使用。回調函數,事件和節點中的許多事物與基本JavaScript相同 – Kundu

+0

@Saransh Node *是* Javascript。您不能以除JavaScript之外的任何其他樣式編寫節點。 – Barney

4

這不是一個風格。這兩個功能完成兩個完全不同的事情。

Closure提供對局部變量的訪問。通過這種方式,您可以創建不可從外部訪問的私有變量(例如,在您的示例中爲url)。但是它會產生性能影響,因爲每次創建對象時都會創建閉包。

Prototype函數速度更快,但它是在對象之前創建的,並且不知道任何關於對象本身的東西。

有時甚至在同一時間使用它們也是有意義的。 :)

PS:編碼風格在這裏描述:https://npmjs.org/doc/coding-style.html。它並不能解釋你的特定問題,但我覺得我必須在以前的答案中將這兩個環節與更明智的東西進行平衡。 :)

+0

什麼使用兩者同時有意義?我認爲你指的是我應該根據我正在編寫的那段特定代碼的需要來使用它們。但是,如果是這種情況,我想知道哪種情況下我應該使用哪一種....這是我的問題 –

+0

「兩者同時」意味着根據傳遞給構造函數的選項來覆蓋某些方法的能力。如果你不知道我在說什麼,只需使用'prototype',因爲它更快。 – alex

+0

你可以建議我一個例子,其中兩個都使用?我完全不理解它。 –

0

這兩種風格都有好處,我認爲這取決於你的模塊/文件試圖公開。我大量使用閉包樣式來處理我在代碼中使用的大多數模塊。 (如db抽象,緩存抽象,郵件等),我使用構造函數/原型創建了很多對象(如雙鏈表中的節點)

===具有內部屬性的對象一個封閉

如果您在其範圍內創建一個對象(讓我們稱它爲self), 添加一堆訪問並附加到該對象的方法(self。X) ,並在年底的出口自我,一切都只能訪問您添加到自己什麼,不能訪問,你對其他創建自

===構造函數和原型

函數內部的局部變量如果您創建構造函數並向它們添加方法/字段,則可以使用原型的每個附加到您實例的函數都可以訪問其內部變量和狀態。

==

有一些事情,與像EventEmitter 和流原型的工作更容易,但它不是很難它們也附加到的對象。

JavaScript是既面嚮對象語言和函數式語言,並在雙方

像適當的繼承見過this.super()。超()缺少重型起重工具。的someMethod()?我沒有 (如果兩個超類都有相同的方法名稱,你需要它)

或功能性編程側的遊牧民族或簡單生成器。

所以對我來說,使用兩者都有意義,並選擇最適合您的問題的。

編輯

存在對我完全忘了對象的一個​​很大的好處。 在第二個例子中,你(在這種情況下異步但是任何延遲執行庫都可以)使用流量控制庫,它使你的代碼,以便更清潔,但

爲您例如工作的http.get有get方法綁定到http,在很多情況下它不是。那麼你的代碼看起來像http.get.bind(http) 如果http是一個對象,並且get在它的作用域中被定義,它將始終工作,並允許你將它傳遞給其他代碼。 (如異步)

0

我用sjsClasshttps://www.npmjs.org/package/sjsclass

代碼示例:

Class.extend('DB', { 
    'protected url': null, 

    __constructor: function (url) { 
     this.url = url; 
    }, 

    info: function (callback) { 
     http.get(this.url + '/info', callback); 
    } 
}); 
1

瓶蓋,當正確完成,允許您通過使用範圍鏈的,可以不封裝數據由任何其他調用者修改。

原型鏈並不提供任何保護。以您所描述的方式使用對象的主要缺點是,特別是在服務器或庫場景中,可以通過調用者修改「this」關鍵字。你無法控制它,如果它發生,你的代碼將以非常不可預知的方式破解。

var mongo = new DB('localhost'); 
mongo.info.call(this); // broken 

現在,它可能不是明確的,但如果你身邊掠過對象或對象屬性,事件處理程序,回調等爲其他功能發生,因爲,你有沒有辦法知道 - 或保護對抗 - 該類型的使用。所以底線是「這個」關鍵字不是你可以存儲的。儘管你可以使用閉包完全控制你的直接範圍。

以類似的方式,你也不能保證你的對象的原型鏈沒有被改變。當然,除非你在對象上創建一個閉包並返回一個包裝。

最後,封閉結構更接近德米特法則,因爲在理論上,您的對象將通過原型鏈「達到」。使用閉包來封裝其他調用允許您公開一個可能導致調用另一個服務方法的方法。這提供了更高的可維護性和靈活性,因爲您現在可以直接控制您直接公開的方法而不依賴原型鏈。當然,LoD只是一種做事的方式,所以對你來說可能是重要的,也可能不重要。

+0

因此,如果API必須公開,那麼您是否傾向於使用閉包;如果其內部應用程序僅由我開發,那麼我認爲原型是安全的? –

+0

是的,這兩種方式都不會有固有的性能問題。這是一種風格選擇,閉包更受保護 - 更接近私人實例變量。但是有兩種框架和插件可以實現這一點,所以最終對您有所幫助。我還要指出,至少,CommonJS模塊使閉包易於使用。但這取決於您的偏好。 –

0

構造可以是這樣的

var db = new DB(); 
... 
if(db instanceof DB){ 
    ... 
} 
使用

閉包可以使私有變量,如

function DB(url) { 
    var urlParam = '&a=b'; 
    return { 
     info: async.apply(http.get, url + '/info' + urlParam) 
    }; 
} 

urlParam是一個私有變量無法獲取或設置

如果你只想要一個靜態班級或簡單班級,請使用閉包。