如何枚举JavaScript对象的属性?

如何枚举JavaScript对象的属性?,javascript,properties,Javascript,Properties,如何枚举JavaScript对象的属性 实际上,我想列出所有定义的变量及其值,但我了解到定义变量实际上会创建窗口对象的属性。非常简单: for(var propertyName in myObject) { // propertyName is what you want // you can get the value like this: myObject[propertyName] } 现在,您将不会以这种方式获取私有变量,因为它们不可用 EDIT:如果不使用hasOwnP

如何枚举JavaScript对象的属性

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

非常简单:

for(var propertyName in myObject) {
   // propertyName is what you want
   // you can get the value like this: myObject[propertyName]
}
现在,您将不会以这种方式获取私有变量,因为它们不可用


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

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


编辑2:如果有人在比您最初编写对象(通过其原型)晚的时间点向您的对象添加属性/方法,则会出现这种情况-虽然这确实可能会导致意外行为,但我个人并不认为这完全是我的问题。只是意见问题。此外,如果我设计的东西在构建对象时使用原型,而代码迭代对象的属性,并且我想要所有继承的属性,那会怎么样?我不会使用
hasOwnProperty()
。然后,比如说,有人后来添加了新属性。如果当时情况不好,那是我的错吗?我不这么认为。我想这就是为什么jQuery,作为一个例子,指定了扩展其工作方式的方法(通过
jQuery.extend
jQuery.fn.extend
)。

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

使用
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()

编辑:我不同意JasonBunting的说法,即我们不需要担心枚举继承属性。枚举您不期望的继承属性会有危险,因为它会改变代码的行为

这个问题在其他语言中是否存在并不重要;事实上它是存在的,JavaScript特别容易受到攻击,因为对对象原型的修改会影响子对象,即使修改是在实例化之后进行的


这就是为什么JavaScript提供了
hasOwnProperty()
,这就是为什么您应该使用它来确保第三方代码(或任何其他可能修改原型的代码)不会破坏您的代码。除了添加一些额外的代码字节外,使用
hasOwnProperty()

没有任何缺点。如果您试图枚举属性以便针对对象编写新代码,我建议使用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"]}'

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

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 (var name in myObject) {
  alert(name);
}
然而,InternetExplorer6、7和8在JavaScript解释器中有一个bug,其结果是一些键没有被枚举。如果运行此代码:

var obj = { toString: 12};
for (var name in obj) {
  alert(name);
}
If将在除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]);
  }
}
for(myObject中的var键){
警报(键);
}
var shadowedKeys=[
“isPrototypeOf”,
“拥有自己的财产”,
“Tolocalesting”,
“toString”,
“价值”
];

对于(var i=0,a=shadowedKeys,l=a.length;i简单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
});
如果您正在使用库,则可以使用函数:


下面是如何枚举对象的属性:

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

for (var key in params) {
  alert(key + "=" + params[key]);
}
在现代浏览器(ECMAScript 5)中,要获取所有可枚举属性,可以执行以下操作:

(检查链接以获取代码段,以便在旧浏览器上向后兼容)

或获取不可枚举的属性:

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

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

其他信息:

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(窗口),结果是我所期望的


5年后编辑:扩展
对象
不是一个好主意,因为它可能会与其他可能希望在对象上使用
的库冲突,并且会导致项目上出现不可预测的行为。@carlos ruana answer是获取对象键的正确方法。

您可以使用
for
循环

如果需要阵列,请使用:

Object.key(object1)


参考

我仍然是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;
}

我认为@bitwiseplatypus只是在说“小心”。我认为JavaScript的for/in应该
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 });
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;
}