我如何枚举JavaScript对象的属性?
这个问题在这里已经有了答案:
够简单:
for(var propertyName in myObject) {
// propertyName is what you want
// you can get the value like this: myObject[propertyName]
}
现在,你不会以这种方式获得私有变量,因为它们不可用。
编辑:@bitwiseplatypus是正确的,除非你使用hasOwnProperty()
方法,你会得到继承的属性 - 但是,我不知道为什么任何熟悉面向对象编程的人会期望更少! 通常情况下,有人提出这个问题已经受到道格拉斯克罗克福德对此的警告,这仍然让我有点困惑。 同样,继承是面向对象语言的正常部分,因此它是JavaScript的一部分,尽管它是典型的。
现在,这就是说, hasOwnProperty()
对于过滤很有用,但我们不需要发出警告,就像在获取继承属性时存在危险一样。
编辑2:@bitwiseplatypus调出应该在某个时间点向对象添加属性/方法的时间比最初编写对象(通过它的原型)时会发生的情况 - 虽然这确实会导致意外的行为,我个人并不认为这完全是我的问题。 只是一个意见问题。 此外,如果我设计的东西是在我的对象构建过程中使用原型,并且具有迭代对象属性的代码,并且我想要所有继承的属性? 我不会使用hasOwnProperty()
。 然后,假设有人稍后添加新的属性。 如果事情在那个时候表现不好,那是我的错吗? 我不这么认为。 我想这就是为什么jQuery,作为一个例子,已经指定了如何扩展它的工作方式(通过jQuery.extend
和jQuery.fn.extend
)。
使用for..in
循环来枚举对象的属性,但要小心。 枚举将不仅返回枚举对象的属性,还返回任何父对象的原型。
var myObject = {foo: 'bar'};
for (var name in myObject) {
alert(name);
}
// results in a single alert of 'foo'
Object.prototype.baz = 'quux';
for (var name in myObject) {
alert(name);
}
// results in two alerts, one for 'foo' and one for 'baz'
要避免在枚举中包含继承的属性,请选中hasOwnProperty()
:
for (var name in myObject) {
if (myObject.hasOwnProperty(name)) {
alert(name);
}
}
编辑:我不同意JasonBunting的声明,我们不需要担心枚举继承属性。 枚举您不期望的继承属性是有危险的,因为它可以改变代码的行为。
这个问题在其他语言中是否存在并不重要; 事实上它存在,并且JavaScript是特别脆弱的,因为即使修改发生在实例化之后,对象原型的修改也会影响子对象。
这就是JavaScript提供hasOwnProperty()
,这就是为什么你应该使用它来确保第三方代码(或其他可能修改原型的代码)不会破坏你的原因。 除了添加一些额外的代码字节之外,使用hasOwnProperty()
没有任何缺点。
已经多次提出的标准方法是:
for (var name in myObject) {
alert(name);
}
但是,Internet Explorer 6,7和8在JavaScript解释器中存在一个错误,它具有某些键未枚举的效果。 如果你运行这个代码:
var obj = { toString: 12};
for (var name in obj) {
alert(name);
}
如果将在除IE以外的所有浏览器中提醒“12”。 IE会简单地忽略这个键。 受影响的关键值是:
isPrototypeOf
hasOwnProperty
toLocaleString
toString
valueOf
要在IE中真正安全,你必须使用如下所示的内容:
for (var key in myObject) {
alert(key);
}
var shadowedKeys = [
"isPrototypeOf",
"hasOwnProperty",
"toLocaleString",
"toString",
"valueOf"
];
for (var i=0, a=shadowedKeys, l=a.length; i<l; i++) {
if map.hasOwnProperty(a[i])) {
alert(a[i]);
}
}
好消息是,EcmaScript 5定义了Object.keys(myObject)
函数,该函数返回一个对象的键作为数组和一些浏览器(例如Safari 4)已经实现它。
上一篇: How do I enumerate the properties of a JavaScript object?
下一篇: How can I set the least significant bit of an integer in C