如何编写高效的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会