2008-10-16 49 views
683

说的特性从而创建一个对象:如何列出一个JavaScript对象

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

什么是要检索的属性名称的列表的最佳方式?即我想与落得一些变量 '钥匙',使得:

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

有点偏离主题,但如果使用underscore.js:`_.keys(myJSONObject)` – 2013-09-28 08:44:25

+0

[如何循环或枚举JavaScript对象?](http:// stackoverfl ow.com/questions/684672/how-do-i-loop-through-or-enumerate-a-javascript-object) – 2016-06-09 17:46:07

回答

868

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

var keys = Object.keys(myObject); 

上面有一个完整的填充工具,但一个简化的版本是:

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

或者更换var getKeysObject.prototype.keys,让你打电话.keys()上的任何对象。扩展原型有一些副作用,我不会推荐这样做。

+16

我会再次更新效果'你可能会试图做到这一点,以反对原型...但不要!“ – AnthonyWJones 2008-10-16 12:44:13

+3

会有人想要说明,为什么不建议将函数添加到Object的原型? – Vishwanath 2012-01-23 10:47:13

+2

这是一个完全不同的问题,它自己的,在这里快速搜索在stackoverflow或谷歌会给你很多阅读 – ximi 2012-03-01 19:48:58

230

由于slashnick指出的那样,你可以使用“为”结构来遍历一个对象的属性名称。但是你会遍历所有属性的对象的原型链的名字。如果你想迭代只是在对象自身的属性,你可以使用Object#hasOwnProperty()方法。因此有以下几点。

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

如萨姆达顿回答,为这个目的的新方法已在被引入:http://kangax.github.com/es5-compat-table/

的新方法说明ECMAScript第5版。 Object.keys()会做你想要什么,并在Firefox 4,铬6,Safari 5及IE 9支持。

您也可以在不支持它的浏览器中轻松实现该方法。但是,其中的一些实现与Internet Explorer不完全兼容。I've detailed this on my blog生产出更兼容的解决方案:

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,一个众所周知的贡献者最近讨论的原型,我实现了解决方法基于代码为他Object.forIn()功能DontEnum发现缺陷here

8

,如果你想获得的元素只,但不是功能那么这段代码可以帮助你

this.getKeys = function() { 

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

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

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

这是我实现HashMap中的一部分,我只是想的钥匙,“这”包含密钥的散列表对象

7

这将适用于大多数浏览器,即使在IE8中,也不需要任何类型的库。我是你的钥匙。

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

在浏览器支持JS 1.8:

[i for(i in obj)] 
13

可按如下方式使用jQuery做:

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

Mozilla有full implementation details如何应对的它不是做一个浏览器” t支持,如果有帮助:

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文件中。

1

建立在接受的答案上。

如果Object有你想要调用的属性说.properties()试试!

var keys = Object.keys(myJSONObject); 

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

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

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

的输出将是:

['name', 'hello'] 
13

对象.getOwnPropertyNames(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://stackoverflow.com/a/23877420/895245

0

您可以使用object-values可重用组件来获取所有对象的值。

例子:

values({ a: 1, b: 2, c: 3 }) // => [1, 2, 3] 

它是如何工作的:

function values(object: {[any]: any}): any[] { 
    const objValues = []; 
    forEach(object, val => objValues.push(val)); 
    return objValues; 
}; 
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; 
}; 
相关问题