197

我知道在 JavaScript 中,对象兼作哈希,但我一直无法找到一个内置函数来获取密钥:

var h = {a:'b', c:'d'};

我想要类似的东西

var k = h.keys() ; // k = ['a', 'c'];

自己编写一个函数来迭代项目并将键添加到我返回的数组中很简单,但是有没有一种标准的更简洁的方法来做到这一点?

我一直觉得它一定是一个我错过但我找不到的简单内置函数!

4

9 回答 9

282

现代 JavaScript (ECMAScript 5) 中有一个称为Object.keys执行此操作的函数:

var obj = { "a" : 1, "b" : 2, "c" : 3};
alert(Object.keys(obj)); // will output ["a", "b", "c"]

可在此处找到兼容性详细信息。

Mozilla 网站上,还有一个用于向后兼容的片段:

if(!Object.keys) Object.keys = function(o){
   if (o !== Object(o))
      throw new TypeError('Object.keys called on non-object');
   var ret=[],p;
   for(p in o) if(Object.prototype.hasOwnProperty.call(o,p)) ret.push(p);
   return ret;
}
于 2011-08-03T03:02:45.150 回答
80

对于需要与客户端浏览器具有较大兼容性的生产代码,我仍然建议Ivan Nevostruev使用 shim 回答以确保Object.keys在旧浏览器中使用。但是,使用 ECMA 的新功能可以获得所需的确切功能defineProperty

从 ECMAScript 5 开始 - Object.defineProperty

从 ECMA5 开始,您可以使用它Object.defineProperty()来定义不可枚举的属性。当前的兼容性还有很多不足之处,但这最终应该可以在所有浏览器中使用。(特别注意当前不兼容IE8!)

Object.defineProperty(Object.prototype, 'keys', {
  value: function keys() {
    var keys = [];
    for(var i in this) if (this.hasOwnProperty(i)) {
      keys.push(i);
    }
    return keys;
  },
  enumerable: false
});

var o = {
    'a': 1,
    'b': 2
}

for (var k in o) {
    console.log(k, o[k])
}

console.log(o.keys())

# OUTPUT
# > a 1
# > b 2
# > ["a", "b"]

但是,由于 ECMA5 已经添加Object.keys,您不妨使用:

Object.defineProperty(Object.prototype, 'keys', {
  value: function keys() {
    return Object.keys(this);
  },
  enumerable: false
});

原始答案

Object.prototype.keys = function ()
{
  var keys = [];
  for(var i in this) if (this.hasOwnProperty(i))
  {
    keys.push(i);
  }
  return keys;
}

编辑:由于这个答案已经存在了一段时间,我将保持上述内容不变。任何阅读本文的人也应该阅读下面 Ivan Nevostruev 的回答。

没有办法使原型函数不可枚举,这导致它们总是出现在不使用的 for-in 循环中hasOwnProperty。如果扩展 Object 的原型不是那么混乱,我仍然认为这个答案是理想的。

于 2008-08-20T21:55:40.643 回答
43

您可以使用Object.keys

Object.keys(h)
于 2013-08-09T18:45:32.110 回答
33

您可以使用Underscore.js,这是一个 JavaScript 实用程序库。

_.keys({one : 1, two : 2, three : 3});
// => ["one", "two", "three"]
于 2011-08-11T14:15:19.743 回答
13

这是你能做的最好的,据我所知......

var keys = [];
for (var k in h)keys.push(k);
于 2008-08-20T21:49:23.203 回答
8

使用jQuery,您可以获得这样的键:

var bobject =  {primary:"red", bg:"maroon", hilite:"green"};
var keys = [];
$.each(bobject, function(key, val){ keys.push(key); });
console.log(keys); // ["primary", "bg", "hilite"]

或者:

var bobject =  {primary:"red", bg:"maroon", hilite:"green"};
$.map(bobject, function(v, k){return k;});

感谢@pimlottc。

于 2012-02-15T12:27:12.087 回答
6

我相信您可以使用 for/in 循环遍历对象的属性,因此您可以执行以下操作:

function getKeys(h) {
  Array keys = new Array();
  for (var key in h)
    keys.push(key);
  return keys;
}
于 2008-08-20T21:51:08.613 回答
4

我想用AnnanFay 的回答

Object.prototype.keys = function () ...

但是,当将它与Google Maps API v3 结合使用时,Google Maps 将不起作用。

然而,

for (var key in h) ...

效果很好。

于 2010-07-24T15:02:00.197 回答
1

如果您只想获取元素,而不是函数,那么此代码可以帮助您:

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 对象。

于 2012-03-01T09:39:09.360 回答