如何列出JavaScript对象的属性?

时间:2008-10-16 10:08:18

标签: javascript

假设我创建了一个对象:

var myObject =
        {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

检索属性名称列表的最佳方法是什么?即我想最终得到一些变量'键',以便:

keys == ["ircEvent", "method", "regex"]

17 个答案:

答案 0 :(得分:986)

在现代浏览器(IE9 +,FF4 +,Chrome5 +,Opera12 +,Safari5 +)中,您可以使用内置的Object.keys方法:

var keys = Object.keys(myObject);

上面有一个完整的polyfill,但简化版本是:

var getKeys = function(obj){
   var keys = [];
   for(var key in obj){
      keys.push(key);
   }
   return keys;
}

或者将var getKeys替换为Object.prototype.keys,以允许您在任何对象上调用.keys()。扩展原型有一些副作用,我不建议这样做。

答案 1 :(得分:245)

正如slashnick指出的那样,您可以使用“for in”构造来迭代对象的属性名称。但是,您将迭代对象原型链中的所有属性名称。如果您想在对象自己的属性上迭代 ,则可以使用Object#hasOwnProperty()方法。因此具有以下内容。

for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        /* useful code here */
    }
}

答案 2 :(得分:97)

正如Sam Dutton回答的那样,ECMAScript第5版中引入了一种用于此目的的新方法。 Object.keys()将执行您想要的操作,并受Firefox 4,Chrome 6,Safari 5和IE 9支持。

您也可以在不支持它的浏览器中轻松实现该方法。但是,其中一些实现与Internet Explorer不完全兼容。这是一个更兼容的解决方案:

Object.keys = Object.keys || (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !{toString:null}.propertyIsEnumerable("toString"),
        DontEnums = [ 
            'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty',
            'isPrototypeOf', 'propertyIsEnumerable', 'constructor'
        ],
        DontEnumsLength = DontEnums.length;

    return function (o) {
        if (typeof o != "object" && typeof o != "function" || o === null)
            throw new TypeError("Object.keys called on a non-object");

        var result = [];
        for (var name in o) {
            if (hasOwnProperty.call(o, name))
                result.push(name);
        }

        if (hasDontEnumBug) {
            for (var i = 0; i < DontEnumsLength; i++) {
                if (hasOwnProperty.call(o, DontEnums[i]))
                    result.push(DontEnums[i]);
            }   
        }

        return result;
    };
})();

请注意,当前接受的答案不包括对 hasOwnProperty()的检查,并将返回通过原型链继承的属性。它也没有考虑Internet Explorer中着名的DontEnum错误,其中原型链上的非可枚举属性导致具有相同名称的本地声明的属性继承其DontEnum属性。

实施 Object.keys()将为您提供更强大的解决方案。

编辑:在最近与Prototype的知名撰稿人kangax进行讨论之后,我根据他的Object.forIn()函数的代码实现了DontEnum错误的解决方法找到here

答案 3 :(得分:28)

请注意,Firefox 4,Chrome 6,Safari 5,IE 9及更高版本支持Object.keys和其他ECMAScript 5方法。

例如:

var o = {"foo": 1, "bar": 2}; 
alert(Object.keys(o));

ECMAScript 5兼容性表:http://kangax.github.com/es5-compat-table/

新方法说明:http://markcaudill.com/index.php/2009/04/javascript-new-features-ecma5/

答案 4 :(得分:21)

<强> Object.getOwnPropertyNames(obj)

除了Object.keys(obj)显示的属性外,此函数还显示了不可枚举的属性。

在JS中,每个属性都有一些属性,包括布尔值enumerable

一般来说,不可枚举的属性更多&#34;内部化&#34;并且不经常使用,但是有时候深入了解它们才能看到真正发生的事情。

示例:

var o = Object.create({base:0})
Object.defineProperty(o, 'yes', {enumerable: true})
Object.defineProperty(o, 'not', {enumerable: false})

console.log(Object.getOwnPropertyNames(o))
// [ 'yes', 'not' ]

console.log(Object.keys(o))
// [ 'yes' ]

for (var x in o)
    console.log(x)
// yes, base

还要注意:

  • Object.getOwnPropertyNamesObject.keys 上原型链查找base
  • for in

有关原型链的更多信息,请访问:https://stackoverflow.com/a/23877420/895245

答案 5 :(得分:16)

答案 6 :(得分:14)

可以使用jQuery执行如下操作:

var objectKeys = $.map(object, function(value, key) {
  return key;
});

答案 7 :(得分:9)

如果您只是尝试获取元素而不是函数,那么此代码可以帮助您

this.getKeys = function() {

    var keys = new Array();
    for(var key in this) {

        if( typeof this[key] !== 'function') {

            keys.push(key);
        }
    }
    return keys;
}

这是我实现HashMap的一部分,我只想要键,&#34;这个&#34;是包含键

的hashmap对象

答案 8 :(得分:8)

这适用于大多数浏览器,即使在IE8中也是如此,并且不需要任何类型的库。 var i是你的关键。

var myJSONObject =  {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; 
var keys=[];
for (var i in myJSONObject ) { keys.push(i); }
alert(keys);

答案 9 :(得分:7)

在支持js 1.8的浏览器下:

[i for(i in obj)]

答案 10 :(得分:6)

Mozilla有full implementation details如何在不支持的浏览器中执行此操作,如果有帮助的话:

if (!Object.keys) {
  Object.keys = (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
        dontEnums = [
          'toString',
          'toLocaleString',
          'valueOf',
          'hasOwnProperty',
          'isPrototypeOf',
          'propertyIsEnumerable',
          'constructor'
        ],
        dontEnumsLength = dontEnums.length;

    return function (obj) {
      if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');

      var result = [];

      for (var prop in obj) {
        if (hasOwnProperty.call(obj, prop)) result.push(prop);
      }

      if (hasDontEnumBug) {
        for (var i=0; i < dontEnumsLength; i++) {
          if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
        }
      }
      return result;
    };
  })();
}

您可以根据需要添加它,但可能包含在脚本堆栈顶部的某种extensions.js文件中。

答案 11 :(得分:4)

由于我几乎在每个项目中使用 underscore.js ,我会使用keys函数:

var obj = {name: 'gach', hello: 'world'};
console.log(_.keys(obj));

输出结果为:

['name', 'hello']

答案 12 :(得分:4)

IE不支持(i in obj)本机属性。这是我能找到的所有道具的清单。

似乎stackoverflow做了一些愚蠢的过滤。

这个列表位于这个谷歌小组帖子的底部: - https://groups.google.com/group/hackvertor/browse_thread/thread/a9ba81ca642a63e0

答案 13 :(得分:3)

以接受的答案为基础。

如果对象有你要调用的属性,请说.properties()试试!

var keys = Object.keys(myJSONObject);

for (var j=0; j < keys.length; j++) {
  Object[keys[j]].properties();
}

答案 14 :(得分:2)

使用ES6及更高版本(ECMAScript 2015),您可以获取所有类似的属性:

let keys = Object.keys(myObject);

如果您想列出所有值:

let values = Object.keys(myObject).map(key => myObject[key]);

答案 15 :(得分:1)

使用Reflect.ownKeys()

var obj = {a: 1, b: 2, c: 3};
Reflect.ownKeys(obj) // ["a", "b", "c"]

Object.keys Object.getOwnPropertyNames 无法获得不可枚举属性。甚至对于不可枚举的属性也可以使用。

var obj = {a: 1, b: 2, c: 3};
obj[Symbol()] = 4;
Reflect.ownKeys(obj) // ["a", "b", "c", Symbol()]

答案 16 :(得分:0)

该解决方案适用于我的案例和跨浏览器:

var getKeys = function(obj) {
    var type = typeof  obj;
    var isObjectType = type === 'function' || type === 'object' || !!obj;

    // 1
    if(isObjectType) {
        return Object.keys(obj);
    }

    // 2
    var keys = [];
    for(var i in obj) {
        if(obj.hasOwnProperty(i)) {
            keys.push(i)
        }
    }
    if(keys.length) {
        return keys;
    }

    // 3 - bug for ie9 <
    var hasEnumbug = !{toString: null}.propertyIsEnumerable('toString');
    if(hasEnumbug) {
        var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
            'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];

        var nonEnumIdx = nonEnumerableProps.length;

        while (nonEnumIdx--) {
            var prop = nonEnumerableProps[nonEnumIdx];
            if (Object.prototype.hasOwnProperty.call(obj, prop)) {
                keys.push(prop);
            }
        }

    }

    return keys;
};