如何列出JavaScript对象的属性?
假设我创建了一个对象:
var myObject =
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
检索属性名称列表的最佳方法是什么? 即,我想最终得到一些变量“键”,使得:
keys == ["ircEvent", "method", "regex"]
在现代浏览器(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;
}
或者用Object.prototype.keys
替换var getKeys
以允许您在任何对象上调用.keys()
。 扩展原型有一些副作用,我不会推荐这样做。
正如Slashnick所指出的那样,您可以使用“for in”构造来迭代对象的属性名称。 但是,您将迭代对象原型链中的所有属性名称。 如果你想只在对象自身的属性进行迭代,你可以使用对象#hasOwnProperty()方法。 因此有以下几点。
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
/* useful code here */
}
}
正如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()将为您提供更强大的解决方案。
编辑:继最近与kangax讨论之后,我为Prototype的知名贡献者开发了一个基于他的Object.forIn()
函数代码的DontEnum bug的解决方法。
上一篇: How to list the properties of a JavaScript object?
下一篇: How can I merge properties of two JavaScript objects dynamically?