for..in和hasOwnProperty

可能重复:
如何检查一个对象是否在Javascript中有一个属性?

我在Twitter的JS文件中find以下代码片段。 我想知道为什么他们需要调用hasOwnProperty函数来看'字典'有'键'属性? for循环为“dict”中的每个“键”运行,这意味着“dict”具有“键”,我错过了一个点吗?

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

因为如果你不这么做的话,它会循环遍历原型链上的每个属性,包括你不知道的属性(可能是有人用本地对象原型搞乱的)。

这样你只能保证那个对象实例本身的密钥。

hasOwnProperty方法让你知道一个属性是直接在一个对象的实例上还是从它的原型链inheritance的。

考虑以下几点

 function ObjWithProto() { this.foo = 'foo_val'; } ObjWithProto.prototype = {bar: 'bar_val'}; var dict = new ObjWithProto(); dict.foobar = 'foobar_val'; 

即你有一个带有属性foofoobarObject dict ,它也从它的原型链inheritance一个属性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 

这可以让你分离一个对象本身和它所inheritance的属性(通常是与循环无关的方法)

此外,如果你现在做dict.bar = 'new_bar_val'; ,最后的结果会变成has bar new_bar_val ,让你甚至可以区分与inheritance的同名属性。

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

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

但是这个函数是从Object类inheritance的,所以hasOwnProperty会告诉你这个键是由字典所有,还是inheritance的。

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

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