
之前的幾條都不斷地重複着for...in循環,它便利好用,但又容易被原型污染。for...in循環最常見的用法是枚舉字典中的元素。這裡就是從側面提出不要在共享的Object.prototype中增加可枚舉的屬性。這就導緻,我們在開發的時候,不能在Object.prototype中添加有用的方法。如,我們想增加一個産生對象屬性名數組的allKeys方法将會怎麼樣?Object.prototype.a
之前的幾條都不斷地重複着for...in循環,它便利好用,但又容易被原型污染。for...in循環最常見的用法是枚舉字典中的元素。這裡就是從側面提出不要在共享的Object.prototype中增加可枚舉的屬性。
這就導緻,我們在開發的時候,不能在Object.prototype中添加有用的方法。如,我們想增加一個産生對象屬性名數組的allKeys方法将會怎麼樣?
Object.prototype.allKeys=function(){
var res=[];
for(var key in this){
res.push(key);
}
return res;
}
上面的方法污染了它自身。
({a:1,b:2,c:3}).allKeys();//['allKeys','a','b','c']
可以用之前說的方法改進allKeys方法忽略掉Object.prototype中的屬性。
獨立為函數
把要添加的方法獨立為一個函數。
function allKeys(obj){
var res=[];
for(var key in this){
res.push(key);
}
return res;
}
這樣就可以使用,而又可以不污染到原型。for...in循環也不會出錯。
設定為不可枚舉
如果想在Object.prototype中增加屬性,ES5提供了Object.defineProperty方法,可以定義一個對象的屬性并指定該屬性的中繼資料。通過設定其可枚舉性為false使其在for...in循環中不可見。
Object.defineProperty(Object.prototype,'allKeys',{
value:function(){
var res=[];
for(var key in this){
res.push(key);
}
return res;
},
writable:true,
enumerable:false,
configurable:true
});
調用一下可得
({a:1,b:2,c:3}).allKeys();//['a','b','c']
上面的代碼不會污染其他所有Object執行個體的所有for...in循環。事實上,當你需要增加一個不應該在for...in循環中出現的屬性時,Object.defineProperty方法可以用來定義屬性。
提示
- 避免在Object.prototype中增加屬性
- 考慮編寫一個函數代替Object.prototype方法
- 如果你确定需要在Object.prototype中增加屬性,使用ES5中的Object.defineProperty方法将它們定義為不可枚舉的屬性
版權聲明
翻譯的文章,版權歸原作者所有,隻用于交流與學習的目的。
原創文章,版權歸作者所有,非商業轉載請注明出處,并保留原文的完整連結。