这个问题在这里已经有答案了:

如何枚举 JavaScript 对象的属性?

我实际上想列出所有定义的变量及其值,但我了解到定义变量实际上会创建窗口对象的属性。

有帮助吗?

解决方案

足够简单:

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

现在,您将无法通过这种方式获得私有变量,因为它们不可用。


编辑: @bitwiseplatypus 是正确的,除非您使用 hasOwnProperty() 方法,您将获得继承的属性 - 但是,我不知道为什么熟悉面向对象编程的人会期望更少的东西!通常,提出这个问题的人都会受到道格拉斯·克罗克福德(Douglas Crockford)对此的警告,这仍然让我有点困惑。同样,继承是 OO 语言的正常部分,因此也是 JavaScript 的一部分,尽管它是原型的。

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

编辑2: @bitwiseplatypus 提出了如果有人在比您最初编写对象(通过其原型)晚的时间点向您的对象添加属性/方法时会发生的情况 - 虽然这确实可能会导致意外的行为,但我个人不这样做我完全不认为这是我的问题。只是意见问题。此外,如果我的设计方式是在构建对象期间使用原型,但又具有迭代对象属性的代码,并且我想要所有继承的属性,该怎么办?我不会用 hasOwnProperty(). 。然后,假设有人稍后添加了新属性。如果当时事情表现得很糟糕,那是我的错吗?我不这么认为。我认为这就是为什么 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'

为了避免在枚举中包含继承的属性,请检查 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) 已经实现了。

在现代浏览器(ECMAScript 5)中,要获取所有可枚举属性,您可以执行以下操作:

对象.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.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]);
}

简单的 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
});

我找到了... for (property in object) { // do stuff } 将列出所有属性,以及窗口对象上所有全局声明的变量。

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

var params = { name: 'myname', age: 'myage' }

for (var key in params) {
  alert(key + "=" + params[key]);
}

如果您正在使用 下划线.js 库,您可以使用函数 :

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

您可以使用 for 的循环。

如果你想要一个数组,请使用:

Object.keys(object1)

参考号 对象.keys()

Python 的 dict 有“keys”方法,这非常有用。我认为在 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 的回答非常有效。我测试了Object.keys(window),结果符合我的预期。

5年后编辑:延长不是一个好主意 Object, ,因为它可能与其他可能想要使用的库发生冲突 keys 他们的对象上,这将导致您的项目出现不可预测的行为。@carlos-ruana 答案是获取对象键的正确方法。

如果您尝试枚举属性以便针对对象编写新代码,我建议使用 Firebug 等调试器来直观地查看它们。

另一种方便的技术是使用 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

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

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;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top