2008-10-16 51 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; 
}; 
相關問題