2017-07-29 37 views
0

Here它說:原型如何初始化實例變量可以提高性能

將實例變量聲明/在樣機值類型(而不是引用類型)初始化值實例變量初始化(即類型的值數字,布爾值,null,未定義或字符串)。這樣可以避免在每次調用構造函數時不必要地運行初始化代碼。 (這不能爲實例變量,其初始值取決於參數構造函數,或其他一些國家在建設的時間內完成。)

,它給的,而不是下面的例子中,:

foo.Bar = function() { 
    this.prop1_ = 4; 
    this.prop2_ = true; 
    this.prop3_ = []; 
    this.prop4_ = 'blah'; 
}; 

用途:

foo.Bar = function() { 
    this.prop3_ = []; 
}; 

foo.Bar.prototype.prop1_ = 4; 
foo.Bar.prototype.prop2_ = true; 
foo.Bar.prototype.prop4_ = 'blah'; 

現在,我創建了foo.Bar WRT的兩個實例第二個方案:

foo = {} 
f1 = new foo.Bar() 
f2 = new foo.Bar() 

,然後進行測試:

f1.prop1_ // gives 4 
f1.prop1_ = 5 // changed it 
f2.prop1_ // still gives 4 
Object.getPrototypeOf(f1) === Object.getPrototypeOf(f2) // true 

現在我的問題:雖然f1f2共享相同的原型,每一個原型似乎有不同的範圍,因此,(罩?)他們有自己的prop1_副本;這意味着分開的內存分配發生。爲什麼這是一個性能增益?

回答

1

它更高效,因爲你沒有在構造函數中運行一堆賦值代碼,這應該是顯而易見的。它在原型上共享相同的值,因爲在原型上共享任何東西。

的事情是,當你閱讀f1.prop1_,它看起來了從原型鏈中的價值,因爲f1本身不具有財產prop1_但是,當您分配給屬性f1.prop1_ = 5,它將直接分配給f1對象上的屬性。換句話說,分配會在對象本身上創建屬性。原型值此後被實例屬性所遮蔽。這就是爲什麼實例會有不同的值。

這對於不可變的值是很好的;對於像數組這樣的可變值來說這是一個糟糕的主意,因爲f1.arr_.push(foo)會改變原型上的對象而不是在單個實例上創建屬性。

+0

我已閱讀,某處,但我必須親身體驗它;) – mehmet

1

號,如果你創建兩個實例,整個原型鏈是這樣的:

foo.Bar.prototype { 
    prop1_ :4 
} 
f1{ 
    proto:foo.Bar.prototype 
} 
f2{ 
    proto:foo.Bar.prototype 
} 

所以當你

f1.prop1_ 

它檢查是否在F1中存在的屬性(其不),然後它在原型中查找它,並評估爲4。

如果你

f1.prop1_ = 1; 

它並不設置原型的屬性,但該元素本身:

foo.Bar.prototype { 
    prop1_ :4 
} 
f1{ 
    proto:foo.Bar.prototype 
    prop1_:1 
} 
f2{ 
    proto:foo.Bar.prototype 
} 

所以結果:

f1.prop1_ // 1 
f2.prop2_ // 4 (looked up in prototype)