for..in和hasOwnProperty

时间:2012-10-04 20:55:56

标签: javascript

  

可能重复:
  How do I check to see if an object has a property in Javascript?

我在Twitter的JS文件中找到了以下代码段。我想知道为什么他们需要调用hasOwnProperty函数才能看到dict具有key属性? for循环正在为'dict'中的每个'key'运行,这意味着'dict'有'key',我错过了一个点吗?

function forEach(dict, f) {
    for (key in dict) {
        if (dict.hasOwnProperty(key))
            f(key, dict[key]);
    }
}

4 个答案:

答案 0 :(得分:67)

因为如果你不这样做,它将循环遍历原型链上的每个属性,包括那些你不知道的属性(可能是由于某人搞乱了原生对象原型而添加的)。

这样,您只能保证该对象实例本身的密钥。

答案 1 :(得分:31)

hasOwnProperty 方法可让您知道属性是直接在对象的实例上还是从其原型链继承。

考虑以下

function ObjWithProto() {
    this.foo = 'foo_val';
}

ObjWithProto.prototype = {bar: 'bar_val'};

var dict = new ObjWithProto();
dict.foobar = 'foobar_val';

即。您有一个对象 dict,其属性foofoobar也会从其原型链继承属性bar

现在运行代码

(修改后的版本)
function forEach(dict) {
    var key;
    for (key in dict) {
        if ( dict.hasOwnProperty(key) ) console.log('has', key, dict[key]);
        else console.log('not', key, dict[key]);
    }
}
forEach( dict );

你会看到

has foo foo_val
has foobar foobar_val
not bar bar_val

这使您可以分离对象拥有的属性和它继承的属性(通常是与循环无关的方法)

此外,如果您现在执行dict.bar = 'new_bar_val';,则最后的结果将更改为has bar new_bar_val,这样您甚至可以区分与继承的名称相同的属性。

答案 2 :(得分:5)

javascript上的每个对象都是一个字典,这意味着“toString”和其他每个方法都是每个对象的关键

var myObj = {};
console.log(myObj["toString"]);

但是这个函数是从Object类继承的,所以hasOwnProperty告诉你这个键是否属于字典,或者它是否被继承。

"toString" in myObj; // true
myObj.hasOwnProperty("toString") // false

答案 3 :(得分:1)

@blockhead就在这里。例如,Prototype.js框架用于使用额外的辅助方法扩展本机数组(我不知道当前版本的框架的情况)。 因此,直接使用“for(key in dict)”将返回div的所有元素以及对辅助方法的引用。这有点出乎意料:)