如何列出 JavaScript 对象的属性?

IT技术 javascript
2021-02-05 13:22:51

假设我创建了一个对象:

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

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

keys == ["ircEvent", "method", "regex"]
6个回答

在现代浏览器(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 getKeysObject.prototype.keys以允许您调用.keys()任何对象。扩展原型有一些副作用,我不建议这样做。

有没有人想点亮,为什么不建议在Object的原型中添加函数?
2021-03-16 13:22:51
我会再次更新大意是“你可能想这样做来对象原型......但不要!”
2021-03-19 13:22:51
for (var key in myObject) {...}技术对于浏览器和 V8 之外的 javascript 运行时很有用。例如,当将 javascript map-reduce 查询传递给 Riak 时,Object对象不存在,因此该Object.keys方法不可用。
2021-03-26 13:22:51
这本身就是一个完全不同的问题,在 stackoverflow 或谷歌上快速搜索会给你很多阅读
2021-03-29 13:22:51
@slashnick 你的“简化版本”返回对象原型链中的所有属性(因为它使用“for ... in”),而(ECMAScript 5.1)Object.keys方法只返回对象自己的属性。我认为这是一个重要的区别。
2021-04-05 13:22:51

正如slashnick指出的那样,您可以使用“for in”构造来迭代对象的属性名称。但是,您将迭代对象原型链中的所有属性名称。如果你想迭代只是在对象自己的属性,你可以利用的对象#hasOwnProperty()方法。从而有以下。

for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        /* useful code here */
    }
}
这是 Zakas 本人关于该主题的一篇优秀文章:nczonline.net/blog/2010/07/27/...
2021-03-21 13:22:51
大声笑@MarkHenderson - 但下次,只需杀死浏览器的进程并重新启动它,而不是浪费 15 分钟 :)
2021-03-23 13:22:51
我希望我在上面 slashnic 的回答之前读过这篇文章。我只需要花 15 分钟按住esc键,因为该对象有大约一百万个属性,其中大部分没有使用,我对此有一个警报。
2021-03-29 13:22:51
@MarkHenderson 为什么不使用 console.log?
2021-04-05 13:22:51
一个相关的函数是 obj.getOwnPropertyNames() - developer.mozilla.org/en-US/docs/JavaScript/Reference/...
2021-04-06 13:22:51

正如 Sam Dutton 所回答的那样,ECMAScript 5th Edition 中引入了一种用于此目的的新方法。 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 错误的解决方法

我已将此解决方案集成到 es5-shim github.com/kriskowal/es5-shim/blob/master/es5-shim.js#L390
2021-03-11 13:22:51
很好的答案,我认为接受的答案仍然是性能最高的准确解决方案,假设它始终是 JSON dict。这当然是在其他地方使用的。
2021-03-23 13:22:51
非常好,安迪 :) 我只想提醒 - 在这个线程中似乎没有人提到 - ES5Object.keys只返回与对象的可枚举属性相对应的字符串数组这在使用原生(用户定义)对象时可能不是很重要,但是对于宿主对象应该非常明显(尽管未指定宿主对象的行为是一个单独的——痛苦的——故事)。为了枚举所有(包括不可枚举的)属性,ES5 提供了Object.getOwnPropertyNames(在我的兼容表中查看它的支持——kangax.github.com/es5-compat-table
2021-03-25 13:22:51
@David Caunt:谢谢:-) 不幸的是,接受的答案仍然会与 DontEnum 错误发生冲突,并且您永远不知道什么 JSON 对象可能将诸如“valueOf”或“constructor”之类的字符串作为其键之一。它还将迭代扩展到Object.prototype. 然而,通常情况下,较短的代码看起来比更大、更健壮的代码更有吸引力,但这个答案的重点是使用 ECMAScript 5th's Object.keys(),它可以在不支持它的浏览器中使用此代码实现。本机版本的性能甚至会比这更好。
2021-03-26 13:22:51
有人可以解释为什么这是实现为Object.keys(stuff)而不是stuff.keys()
2021-03-27 13:22:51

请注意,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/

还可以在控制台中查看 Chrome Dev Tools、Firebug 等的 keys()。
2021-03-25 13:22:51

Object.getOwnPropertyNames(obj)

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

在 JS 中,每个属性都有一些属性,包括一个 boolean enumerable

一般而言,不可枚举的属性更“内在”且不常使用,但有时查看它们以了解真正发生的事情是很有见地的。

例子:

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.getOwnPropertyNames并且Object.keys 不要上原型链去寻找base
  • for in

更多关于原型链的信息:https : //stackoverflow.com/a/23877420/895245