首页 文章

如何枚举JavaScript对象的属性? [重复]

提问于
浏览
597

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

如何枚举JavaScript对象的属性?

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

14 回答

  • 754

    很简单:

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

    现在,您不会以这种方式获取私有变量,因为它们不可用 .


    编辑:@bitwiseplatypus是正确的,除非你使用 hasOwnProperty() 方法,你将获得继承的属性 - 但是,我没有't know why anyone familiar with object-oriented programming would expect anything less! Typically, someone that brings this up has been subjected to Douglas Crockford'关于此的警告,这仍然让我感到困惑 . 同样,继承是OO语言的正常部分,因此它是JavaScript的一部分,尽管它是典型的 .

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

    编辑2:@bitwiseplatypus提出了如果有人在您最初编写对象(通过其原型)之后的某个时间点向对象添加属性/方法时会发生的情况 - 虽然这可能会导致意外行为,我个人不要't see that as my problem entirely. Just a matter of opinion. Besides, what if I design things in such a way that I use prototypes during the construction of my objects and yet have code that iterates over the properties of the object and I want all inherited properties? I wouldn' t使用 hasOwnProperty() . 然后,让's say, someone adds new properties later. Is that my fault if things behave badly at that point? I don' t这样想 . 我认为这就是为什么jQuery作为示例已经指定了扩展其工作方式的方法(通过 jQuery.extendjQuery.fn.extend ) .

  • 14

    使用 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);
      }
    }
    

    Edit: 我不同意JasonBunting 's statement that we don'需要担心枚举继承的属性 . 枚举您不期望的继承属性存在危险,因为它可以更改代码的行为 .

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

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

  • 6

    已经多次提出的标准方法是:

    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)已经实现了它 .

  • 212

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

    Object.keys(obj)(检查链接以获取旧版浏览器向后兼容性的代码段)

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

    Object.getOwnPropertyNames(obj)

    Check ECMAScript 5 compatibility table

    其他信息:What is a enumerable attribute?

  • 22

    我认为令我感到意外的一个例子是相关的:

    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 );
        }
      }
    };
    
  • 0
    for (prop in obj) {
        alert(prop + ' = ' + obj[prop]);
    }
    
  • 49

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

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

  • 9

    如果您使用Underscore.js库,则可以使用函数keys

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

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

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

    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年后编辑:扩展 Object 并不是一个好主意,因为它可能与其他可能想要在其对象上使用 keys 的库发生冲突,并且会导致项目出现不可预测的行为 . @ carlos-ruana回答是获取对象键的正确方法 .

  • 8

    您可以使用 for 循环 .

    如果你想使用数组:

    Object.keys(object1)

    参考 . Object.keys()

  • 2

    如果您尝试枚举属性以便针对该对象编写新代码,我建议使用像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

  • 0

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

相关问题