2012-12-04 43 views
11

在JavaScript中,對象的字段始終是「公共」:類中的javascript私有成員是否會導致巨大的內存開銷?

function Test() { 
    this.x_ = 15; 
} 
Test.prototype = { 
    getPublicX: function() { 
    return this.x_; 
    } 
}; 
new Test().getPublicX();  // using the getter 
new Test().x_;     // bypassing the getter 

,但你可以通過使用一個局部變量,並用封口吸氣模擬一個「私」領域:

function Test() { 
    var x = 15; 
    this.getPrivateX = function() { 
    return x; 
    }; 
} 
new Test().getPrivateX();  // using the getter 
// ... no way to access x directly: it's a local variable out of scope 

一個區別是,與「公」的做法,每個實例的getter是相同的函數對象:

console.assert(t1.getPublicX === t2.getPublicX); 

,而與「私」的方式,每實例的getter是一個獨特的函數對象:

console.assert(t1.getPrivateX != t2.getPrivateX); 

我很好奇這種方法的內存使用情況。由於每個實例都有單獨的getPrivateX,如果我創建了10k個實例,會造成巨大的內存開銷嗎?

與私人和公共的成員創建類的實例性能測試:

Jsperf

+1

相關:http://stackoverflow.com/questions/6204526/understanding-javascript -closures-and-memory-usage – tjameson

+1

可能的重複:http://stackoverflow.com/questions/2239533/javascript-private-methods-what-is-the-memory-impact?rq=1 – tjameson

+4

公共和私人方法是線性的 - 'O(n)' - 在資源消耗方面(只有不同​​的'C')。因爲它最終是一個實現細節,所以要知道它是否「[使用太多的內存開銷]」的唯一方法是運行一些測試。對於已知*的對象有10k +(100k +?)實例,我會首先選擇僅​​用於原型的方法;這是*我自己未經證實的*「表演」強制。但是,這一切都是線性增長。 – 2012-12-04 19:05:16

回答

6

當然它會造成內存開銷。在公開的情況下,你的函數不屬於實例,這意味着只有一個實例,除非你明確地給出了一個特定的對象,它是它自己的那個函數的實例。在私人情況下,函數屬於實例,這意味着您需要執行內存管理。

我的意思是以下幾點:

var t1 = new Test(); 
t1.getPublicX = function() { 
    return true; 
} 

var t2 = new Test(); 

t1.getPublicX(); // Returns true 
t2.getPublicX(); // Returns 15 

所以,你可以在公共成員相同的情況下結束了爲好。一般來說,對你的問題的回答是:是的,當實例化大量對象時會有內存開銷。

我還要補充一點的publicprivatejavascript概念並不是在所有的相同C++。在C++專用封裝成員只能從類內訪問,這在javascript您仍然可以從任何地方訪問該成員。

而且在經過短暫測試後,開銷實際上並不重要。的標籤需要40MB超過(與谷歌加載​​)沒有它作爲顯示在下面的截圖:

enter image description here

Link to full size image.

相關問題