如何列出 JavaScript 对象的属性?
Posted
技术标签:
【中文标题】如何列出 JavaScript 对象的属性?【英文标题】:How to list the properties of a JavaScript object? 【发布时间】:2010-09-17 12:08:09 【问题描述】:假设我这样创建了一个对象:
var myObject =
"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*";
检索属性名称列表的最佳方法是什么?即我想最终得到一些可变的“键”:
keys == ["ircEvent", "method", "regex"]
【问题讨论】:
有点离题,但如果你使用 underscore.js:_.keys(myJSONObject)
TL;DR: 如果您只需要可枚举的属性:Object.keys(obj)
有时您也需要不可枚举的属性。如果你这样做,请务必记住这一点!要获取它们,请使用 Object.getOwnPropertyNames(obj)
***.com/a/32413145/1599699
【参考方案1】:
在现代浏览器(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()
。扩展原型有一些副作用,我不建议这样做。
【讨论】:
我会再次更新,大意是“您可能很想对对象原型执行此操作……但不要这样做!” 有人要开灯吗,为什么不建议在Object的原型中添加函数? 这本身就是一个完全不同的问题,在 *** 或谷歌上快速搜索会让你有很多阅读内容for (var key in myObject) ...
技术对于浏览器和 V8 之外的 javascript 运行时很有用。例如,当将 javascript map-reduce 查询传递给 Riak 时,Object
对象不存在,因此 Object.keys
方法不可用。
@slashnick 您的“简化版本”返回对象原型链中的所有属性(因为它使用“for ... in”),而(ECMAScript 5.1)Object.keys
方法只返回对象自身的属性。我认为这是一个重要的区别。【参考方案2】:
正如slashnick 所指出的,您可以使用“for in”构造来遍历对象以获取其属性名称。但是,您将遍历对象原型链中的所有属性名称。如果您想仅迭代对象自身的属性,您可以使用Object#hasOwnProperty() 方法。因此具有以下内容。
for (var key in obj)
if (obj.hasOwnProperty(key))
/* useful code here */
【讨论】:
我希望我在上面 slashnic 的回答之前读过这个。我只需要花 15 分钟按住esc
键,因为该对象有大约一百万个属性,其中大部分没有使用,而且我有一个警报。
这是 Zakas 本人关于该主题的出色文章:nczonline.net/blog/2010/07/27/…
LOL @MarkHenderson - 但下一次,只需终止浏览器的进程并重新启动它,而不是浪费 15 分钟 :)
一个相关的函数是 obj.getOwnPropertyNames() - developer.mozilla.org/en-US/docs/JavaScript/Reference/…
@MarkHenderson 你为什么不使用console.log?【参考方案3】:
正如 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 .
【讨论】:
很好的答案,我认为接受的答案仍然是最准确的解决方案,假设它总是一个 JSON 字典。这肯定是在其他地方使用的。 @David Caunt:谢谢 :-) 不幸的是,接受的答案仍然会与 DontEnum 错误相冲突,而且您永远不知道 JSON 对象可能具有像“valueOf”或“constructor”这样的字符串作为一个它的钥匙。它还将迭代对Object.prototype
的扩展。但是,通常情况下,较短的代码看起来比更大、更健壮的代码更具吸引力,但这个答案的重点是使用 ECMAScript 5th 的 Object.keys()
,它可以在不支持它的浏览器中实现代码。原生版本的性能会比这更好。
非常好,Andy :) 我想提醒一下——似乎没有人在这个帖子中提到——ES5 Object.keys
只返回对应于 enumerable的字符串数组> 对象的属性。这在使用本地(用户定义的)对象时可能并不重要,但对于宿主对象应该非常明显(尽管未指定的宿主对象行为是一个单独的——痛苦的——故事)。为了枚举所有(包括不可枚举的)属性,ES5 提供了Object.getOwnPropertyNames
(在我的兼容表中查看它的支持——kangax.github.com/es5-compat-table)
我已将此解决方案集成到 es5-shim github.com/kriskowal/es5-shim/blob/master/es5-shim.js#L390
有人能解释一下为什么这是Object.keys(stuff)
而不是stuff.keys()
吗?【参考方案4】:
请注意,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 开发工具、Firebug 等的 keys()。 markcaudill.com/index.php/2009/04/javascript-new-features-ecma5 未找到【参考方案5】:Object.getOwnPropertyNames(obj)
除了Object.keys(obj)
显示的属性之外,此函数还显示不可枚举的属性。
在 JS 中,每个属性都有几个属性,包括一个布尔值 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://***.com/a/23877420/895245
【讨论】:
【参考方案6】:我是转储功能的忠实粉丝。
http://ajaxian.com/archives/javascript-variable-dump-in-coldfusion
【讨论】:
+1 因为我来到这里的目的是构建类似的东西(尽管不是那么好)。 netgrow.com.au/assets/files/dump/dump.zip not found 如何下载转储javascript? @Kiquenet 每次我想构建这样的东西时,我都会选择常规的对象检查器,如果你想用 html 呈现它,可以使用 npm modules 之类的东西。坦率地说,让我陷入困境的是,我想要比图片上的更好的东西,但从未设法将其概念化。在检查器中浏览对象很糟糕,但是尝试从任意对象中推断出含义的启发式方法(例如,将对象数组分类到带有列的表中)在实践中并不总是有效。 关于 Pretty Print Javascripthttps://j11y.io/demos/prettyprint/
是什么?【参考方案7】:
可以用 jQuery 做如下:
var objectKeys = $.map(object, function(value, key)
return key;
);
【讨论】:
【参考方案8】:如果您只尝试获取元素而不是函数,那么此代码可以帮助您
this.getKeys = function()
var keys = new Array();
for(var key in this)
if( typeof this[key] !== 'function')
keys.push(key);
return keys;
这是我的 HashMap 实现的一部分,我只想要键,“this”是包含键的 hashmap 对象
【讨论】:
【参考方案9】:这适用于大多数浏览器,甚至在 IE8 中,并且不需要任何类型的库。 var i 是您的密钥。
var myJSONObject = "ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*";
var keys=[];
for (var i in myJSONObject ) keys.push(i);
alert(keys);
【讨论】:
您的回答与已经发布的类似,还有什么要补充的吗?【参考方案10】:在支持js 1.8的浏览器下:
[i for(i in obj)]
【讨论】:
【参考方案11】: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
文件中。
【讨论】:
MDN 实现是基于 Andy E 的,它已经作为答案给出。【参考方案12】:使用Reflect.ownKeys()
var obj = a: 1, b: 2, c: 3;
Reflect.ownKeys(obj) // ["a", "b", "c"]
Object.keys 和 Object.getOwnPropertyNames 无法获得 non-enumerable 属性。它甚至适用于不可枚举的属性。
var obj = a: 1, b: 2, c: 3;
obj[Symbol()] = 4;
Reflect.ownKeys(obj) // ["a", "b", "c", Symbol()]
【讨论】:
【参考方案13】:基于已接受的答案。
如果对象有你想调用的属性说 .properties() 试试!
var keys = Object.keys(myJSONObject);
for (var j=0; j < keys.length; j++)
Object[keys[j]].properties();
【讨论】:
【参考方案14】:由于我几乎在每个项目中都使用 underscore.js,所以我会使用 keys
函数:
var obj = name: 'gach', hello: 'world';
console.log(_.keys(obj));
输出将是:
['name', 'hello']
【讨论】:
这是一个用于常用 javascript 功能的工具集库:underscorejs.org【参考方案15】:使用 ES6 及更高版本(ECMAScript 2015),您可以像这样获得所有属性:
let keys = Object.keys(myObject);
如果你想列出所有值:
let values = Object.keys(myObject).map(key => myObject[key]);
【讨论】:
【参考方案16】:IE 不支持原生属性的 for(i in obj)。这是我能找到的所有道具的列表。
似乎 *** 做了一些愚蠢的过滤。
该列表可在此 google 群组帖子的底部找到:- https://groups.google.com/group/hackvertor/browse_thread/thread/a9ba81ca642a63e0
【讨论】:
【参考方案17】:该解决方案适用于我的案例和跨浏览器:
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;
;
【讨论】:
【参考方案18】:这里有很多答案...这是我的 2 美分。
我需要一些东西来打印出所有 JSON 属性,即使是带有子对象或数组(包括父名称)的那些。
所以 - 对于这个 JSON:
mylittleJson =
"one": "blah",
"two":
"twoone": "",
"twotwo": "",
"twothree": ['blah', 'blah']
,
"three": ""
它会打印这个:
.one
.two.twoone
.two.twotwo
.two.twothree
.three
这里是函数
function listatts(parent, currentJson)
var attList = []
if (typeof currentJson !== 'object' || currentJson == undefined || currentJson.length > 0)
return
for(var attributename in currentJson)
if (Object.prototype.hasOwnProperty.call(currentJson, attributename))
childAtts = listatts(parent + "." + attributename, currentJson[attributename])
if (childAtts != undefined && childAtts.length > 0)
attList = [...attList, ...childAtts]
else
attList.push(parent + "." + attributename)
return attList
希望它也有帮助。
【讨论】:
以上是关于如何列出 JavaScript 对象的属性?的主要内容,如果未能解决你的问题,请参考以下文章
如何列出 javascript 对象的函数/方法? (这甚至可能吗?)