如何列出 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.getOwnPropertyNamesObject.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 Javascript https://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.keysObject.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如何列出全局对象的非原生属性。

javascript如何列出全局对象的非原生属性。

javascript如何列出全局对象的非原生属性。

如何列出 javascript 对象的函数/方法? (这甚至可能吗?)

如何使用HTML中的Javascript从对象获取多个输出?

如何使用 nightwatch.js 或 javascript 列出具有共同属性值的相同元素?