如何找到哈希键?


192

我知道在javascript对象中,哈希值会倍增,但是我一直无法找到内置函数来获取密钥

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

我想要类似的东西

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

自己编写一个函数来遍历所有项并将键添加到返回的数组中很简单,但是有没有一种更干净的标准方法呢?

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


我只是跳入javascript,但此帖子可能会对您有所帮助。dean.edwards.name/weblog/2006/07/enum
杰森·索尔多(Jason Saldo)


1
从键中获取值呢?另外,获取哈希中的键数。
zero_cool

2017年的答案:Object.keys(h)Object.values(h)
有损

Answers:


274

现代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;
}

这不是更自然吗?if(!Object.prototype.keys) Object.prototype.keys = function() { if (this !== Object(this)) throw new TypeError('Object.keys called on non-object'); var ret = [], p; for (p in this) if (Object.prototype.hasOwnProperty.call(this, p)) ret.push(p); return ret; } var x = { a: { A: 1, B: 2, C: 3 }, b: { A: 10, B: 20 } }; alert(x.a.keys());
ekkis 2011年

2
据我了解,这Object.prototype.keyskeys可用于Object的所有子类,因此可用于所有对象。如果您尝试使用OOP,可能会想要。无论如何,这实际上取决于您的要求。
伊万·内沃斯特鲁夫

1
如果使用mootools,则Object.keys()应该在所有浏览器中都可用。
同行2012年

有什么可以在角度模板中使用它吗?它在局部文件中不起作用。
杰·舒克拉

我认为您应该将此问题与代码示例一起作为单独的问题提出。
Ivan Nevostruev

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的原型不是那么混乱,那么这个答案将是理想的。


9
“ hasOwnProperty”排除了此对象原型的属性,这很有用。
ijw

2
答案被接受,因为这是我最终实现它的方式,但是我认为这应该是该语言的内置功能。
帕特

5
请注意,应使用“ for(此变量中的...)...”以避免创建全局变量。
布莱德·G。

5
我避免修改Object.prototype -正如下面另一个注释者所指出的那样,这很容易破坏不检查hasOwnProperty()的脚本。取而代之的是,使用不太面向对象的方法:定义一个“键”功能(如果尚不存在)。(Firefox和Chrome都实现了一个本机keys()函数,该函数完全
可以满足

1
将任何内容添加到Object.prototype似乎是一个坏主意,因为它破坏了每个常规循环,例如:for(数组中的var k){}或for(对象中的var k),以及该成语-尽管可能有问题-非常普遍。例如,根据下面的Matthew Darwin的回答,它破坏了Google Maps。
山姆·沃特金斯


33

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

_.keys({one : 1, two : 2, three : 3}); 
// => ["one", "two", "three"]

好吧,这并不是真正要问的问题,因为@Pat正在寻找内置函数,但这仍然是一个有趣的库,并且它不会进行修改Object.prototype
fresskoma 2011年

2
这些天,我认为使用这些漂亮的小库let比编写自己的实现要有用得多。无论如何,在大多数实际项目中,我们无论如何都使用Underscore或等效库。就个人而言,我宁愿使用Underscore。
kumarharsh 2012年

_.keys(obj).length看看是否有任何键。
chovy 2012年

13

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

var keys = [];
for (var k in h)keys.push(k);

2
当Object.prototype陷入混乱时,这也不起作用。
菲尔(Phil)

4
最好使用它,而不要“与” Object.prototype混淆。如果将内容添加到Object.prototype,似乎一切都会中断:遍历数组/对象的键是一种极为常见的习惯用法。
山姆·沃特金斯

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


3
如果您想走这条路线,不妨使用JQuery.map$.map(h, function(v,k) { return k; });
pimlottc 2012年

6

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

function getKeys(h) {
  Array keys = new Array();
  for (var key in h)
    keys.push(key);
  return keys;
}

4

我想使用上面评分最高的答案

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

但是,当与google maps API v3结合使用时,google maps无法正常工作。

for (var key in h) ...

效果很好。


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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.