如何编写高效的js代码(6)
hasOwnProperty和for...in
hasOwnProperty 是 JavaScript 中唯一一个处理属性但是不查找原型链的函数
而for..in语句是用来查找对象属性时遍历原型链上的所有属性(for in 循环不会遍历那些 enumerable 设置为 false 的属性;比如数组的 length 属性)
一般我们会用for...in循环来遍历某个对象中的所有自定义属性,就像操作字典一样,而for...in又会去查找原型链,如果你在原型链上加入了一个可以被枚举的(enumerable 设置为 true)的属性,那么就会对你的遍历造成污染
Object.prototype.allKeys = function() {
var result = [];
for(varkey in this) {
result.push(key);
}
return result;
};
({ a: 1, b: 2, c: 3}).allKeys();// ["allKeys", "a", "b", "c"]
如上,allkeys属性本身也会被遍历出来,好在ES5提供了一种方式能够让你在原型链上添加方法,同时也不用担心在for...in中被枚举出来(其实就是设置enumerable为false)
Object.defineProperty(Object.prototype,"allKeys", {
value: function() {
var result = [];
for(varkey in this) {
result.push(key);
}
return result;
},
writable: true,
enumerable: false,
configurable: true
});
在枚举的时候不要修改被枚举对象的属性
ES5规范并没有规定如果应对并发修改,它把这个实现的自主权交给了各个js引擎,也就是说当一个对象在被枚举的时候,如果你给它添加属性,新的属性在当前进行的枚举过程中并不保证能被访问到,即在遍历过程中修改对象,遍历出来的结果变得不可预测
var s = {a:1,b:2,c:3};
for(var i in s){
if(i==="a"){
delete s[i];
s.d=4;
}
alert(s[i]);
}
上述代码在不同的浏览器下表现的不一样,谷歌不会输出4,而ie8会