我如何枚举JavaScript对象的属性?

我如何枚举JavaScript对象的属性?

我实际上想要列出所有已定义的variables及其值,但是我已经了解到,定义variables实际上会创build窗口对象的一个​​属性。

够简单:

for(var propertyName in myObject) { // propertyName is what you want // you can get the value like this: myObject[propertyName] } 

现在,你不会以这种方式获得私有variables,因为它们不可用。


编辑: @bitwiseplatypus是正确的,除非你使用hasOwnProperty()方法,你会得到inheritance的属性 – 但是,我不知道为什么有人熟悉面向对象的编程会期望更less! 通常情况下,有人提出这个问题已经受到了道格拉斯·克罗克福德(Douglas Crockford)关于这个问题的警告,这仍然让我感到困惑。 同样,inheritance是面向对象语言的正常部分,因此是JavaScript的一部分,尽pipe它是典型的。

现在说, hasOwnProperty()对于过滤很有用,但是我们不需要发出警告,就像在获取inheritance属性时有一些危险一样。

编辑2: @bitwiseplatypus带来的情况将发生应该有人添加属性/方法的时间点比你最初写对象(通过它的原型)的时间点 – 而这是真的,这可能会导致意外的行为,我个人并不认为这完全是我的问题。 只是一个意见的问题。 此外,如果我devise的东西,我在我的对象的build设过程中使用原型,但有代码迭代的对象的属性,我想要所有的inheritance属性? 我不会使用hasOwnProperty() 。 那么,假设稍后有人添加新的属性。 如果事情在这一点上performance不好,那是我的错吗? 我不这么认为。 我想这就是为什么jQuery,作为一个例子,已经指定了扩展它的工作方式(通过jQuery.extendjQuery.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' 

要避免在枚举中包含inheritance的属性,请选中hasOwnProperty()

 for (var name in myObject) { if (myObject.hasOwnProperty(name)) { alert(name); } } 

编辑:我不同意JasonBunting的声明,我们不必担心枚举inheritance属性。 在枚举inheritance的属性上存在着不期望的危险,因为它可以改变代码的行为。

这个问题在其他语言中是否存在并不重要; 事实是存在的,而且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)已经实现了它。

在现代浏览器(ECMAScript 5)中,您可以执行所有可枚举的属性:

Object.keys(obj) (检查链接以得到一个片段,以在旧浏览器上向后兼容)

或者也可以获得不可枚举的属性:

Object.getOwnPropertyNames(OBJ)

检查ECMAScript 5兼容性表

附加信息: 什么是枚举属性?

我认为一个让我吃惊的案例是相关的:

 var myObject = { name: "Cody", status: "Surprised" }; for (var propertyName in myObject) { document.writeln( propertyName + " : " + myObject[propertyName] ); } 

但令我惊讶的是,输出是

 name : Cody status : Surprised forEach : function (obj, callback) { for (prop in obj) { if (obj.hasOwnProperty(prop) && typeof obj[prop] !== "function") { callback(prop); } } } 

为什么? 页面上的另一个脚本扩展了Object的原型:

 Object.prototype.forEach = function (obj, callback) { for ( prop in obj ) { if ( obj.hasOwnProperty( prop ) && typeof obj[prop] !== "function" ) { callback( prop ); } } }; 
 for (prop in obj) { alert(prop + ' = ' + obj[prop]); } 

我发现它… for (property in object) { // do stuff }将列出所有的属性,因此窗口对象上的所有全局声明variables。

简单的JavaScript代码:

 for(var propertyName in myObject) { // propertyName is what you want. // You can get the value like this: myObject[propertyName] } 

jQuery的:

 jQuery.each(obj, function(key, value) { // key is what you want. // The value is in: value }); 

如果您正在使用Underscore.js库,则可以使用function键 :

 _.keys({one : 1, two : 2, three : 3}); => ["one", "two", "three"] 

以下是枚举对象的属性的方法:

 var params = { name: 'myname', age: 'myage' } for (var key in params) { alert(key + "=" + params[key]); } 

Python的字典有'钥匙'的方法,这是非常有用的。 我认为在JavaScript中我们可以有这样的事情:

 function keys(){ var k = []; for(var p in this) { if(this.hasOwnProperty(p)) k.push(p); } return k; } Object.defineProperty(Object.prototype, "keys", { value : keys, enumerable:false }); 

编辑:但是@ carlos-ruana的答案工作得很好。 我testing了Object.keys(窗口),结果是我所期望的。

如果你想枚举的属性,以写对对象的新代码,我会build议使用像Firebug的debugging器来查看它们的视觉。

另一个方便的技术是使用Prototype的Object.toJSON()来将对象序列化为JSON,这会向您显示属性名称和值。

 var data = {name: 'Violet', occupation: 'character', age: 25, pets: ['frog', 'rabbit']}; Object.toJSON(data); //-> '{"name": "Violet", "occupation": "character", "age": 25, "pets": ["frog","rabbit"]}' 

http://www.prototypejs.org/api/object/tojson

你可以使用for循环。

如果你想要一个数组使用Object.keys(object1)

我仍然是JavaScript的初学者,但我写了一个小函数来recursion地打印一个对象及其子对象的所有属性:

 getDescription(object, tabs) { var str = "{\n"; for (var x in object) { str += Array(tabs + 2).join("\t") + x + ": "; if (typeof object[x] === 'object' && object[x]) { str += this.getDescription(object[x], tabs + 1); } else { str += object[x]; } str += "\n"; } str += Array(tabs + 1).join("\t") + "}"; return str; }