2012-08-29 49 views
3

我是JS新手,讀書Javascript Patterns理解。我可以看到的代碼片段之一:Javascript:如何避免在函數中添加新的屬性?

var myFunc = function param() { 
... 
... 
}; 
myFunc.cache={}; 

這表明一個新的屬性可以被任何人在函數體外部添加。這不破壞封裝嗎?如果程序的其他部分不斷添加新的屬性會使我的對象創建體積龐大?如果某人刪除/修改了由我定義的屬性會怎麼樣?

我不知道我是否稱這爲「問題」是正確的。但如果是這樣,請幫助避免這種情況。

謝謝!

回答

3

JavaScript從未真正有任何選項來保護您的對象,但從ECMAScript 5開始,您現在可以使用freeze對象。

var o = { a: 1, b: 2 }; 
Object.freeze(o); 
console.log(o.a); // 1 
o.a = 2; 
console.log(o.a); // 1 

還有一個新的上下文被稱爲嚴格模式,可以拋出錯誤。

function processObject(o) { 
    "use strict"; 
    delete o.a; // throws a TypeError 
} 
+0

如果我不使用嚴格模式,即使在freeze()之後,我也可以添加/刪除嗎? – WinOrWin

+1

@WinOrWin - 如果不是在嚴格模式下,代碼將會運行,但不會發生任何事情。所以他們可以儘可能多地寫'o.c = 3',但'o'仍然會保持原樣。 – ChaosPandion

0

新的屬性可以在任何時候添加,但它不一定是壞事。覆蓋實現的能力非常強大。

通常情況下,你需要添加方法,對象等的功能樣機,所以儘量

myFunc.prototype.cache = {}; 

最終你要遵循類似的模塊模式

http://www.yuiblog.com/blog/2007/06/12/module-pattern/

http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

使用模塊模式將允許您創建具有privil的「私人」成員通過關閉訪問數據。

1

這不破壞封裝嗎?

是和否。如果使用閉包,則仍然可以擁有「私有」變量,因爲它們不能在實例化時聲明的對象函數之外訪問。例如:

var ObjectPrototype = function() { 
    var privateVariable = "closure-scope value"; 
    var InnerPrototype = function() { 
     this.getPrivate = function() { return privateVariable; }; 
    }; 
    return new InnerPrototype(); 
}; 
var myObject = new ObjectPrototype(); 

由於ObjectPrototype返回InnerPrototype的一個新實例,和privateVariable僅存在於ObjectPrototype閉合,就沒有辦法直接從外部訪問privateVariable。獲得它的價值的唯一方法是通過myObject.getPrivate()。注意:Javascript通過引用傳遞對象和數組,所以此方法只能真正保護簡單的值(除非您小心地返回克隆)。

如果程序的其他部分不斷添加新屬性會怎樣? 如何讓我的對象創建體積龐大?

這是你需要留意的東西。

如果有人刪除/修改了我定義的屬性會怎麼樣?

使用上述封閉範圍方法來防止這種情況。