如何找到对象的键?

IT技术 javascript object key
2021-02-09 06:58:38

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

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

我想要类似的东西

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

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

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

6个回答

现代 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;
}
有什么可以在角度模板中使用它的吗?它在部分内部不起作用。
2021-03-16 06:58:38
如果您使用 mootools,Object.keys() 应该在所有浏览器中都可用。
2021-04-01 06:58:38
这不是更自然吗? 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());
2021-04-08 06:58:38
据我了解,这Object.prototype.keys将使keysObject 的所有子类可用,因此适用于所有对象。如果您尝试使用 OOP,您可能想要这样做。无论如何,这实际上取决于您的要求。
2021-04-12 06:58:38
我认为您应该将此作为单独的问题与代码示例一起提出。
2021-04-14 06:58:38

对于需要与客户端浏览器有很大兼容性的生产代码,我仍然建议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 的回答。

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

我会避免修改 Object.prototype - 正如下面的另一位评论者指出的那样,这很容易破坏不小心检查 hasOwnProperty() 的脚本。相反,使用对 OO 不太友好的方式:如果它不存在,则定义一个“键”函数。(Firefox 和 Chrome 都实现了一个原生的 keys() 函数,它完全符合 OP 的要求——IE 没有)
2021-03-15 06:58:38
向 Object.prototype 添加任何内容似乎是一个坏主意,因为它会破坏每个正常循环,例如:for (var k in array) { } 或 for (var k in object),以及那个习惯用法 - 尽管它可能有问题——极其普遍。例如,根据下面马修达尔文的回答,它打破了谷歌地图。
2021-03-22 06:58:38
答案被接受,因为这就是我最终实现它的方式,但我觉得这应该是该语言的内置功能。
2021-03-26 06:58:38
请注意,您应该使用“for (var i in this)...”来避免创建全局变量。
2021-03-26 06:58:38
'hasOwnProperty' 不包括此对象原型的属性,了解这一点很有用。
2021-03-28 06:58:38

您可以使用Object.keys

Object.keys(h)
在 ECMAScript 5 中添加但现在应该可以在大多数主要浏览器中使用
2021-03-17 06:58:38

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

_.keys({one : 1, two : 2, three : 3});
// => ["one", "two", "three"]
_.keys(obj).length 看看有没有钥匙。
2021-04-01 06:58:38
现在,我认为使用这些漂亮的小库比继续编写自己的实现更有帮助......无论如何,在大多数实际项目中,我们无论如何都使用 Underscore 或等效库。就个人而言,我更愿意使用 Underscore。
2021-04-13 06:58:38
好吧,这并不是真正的要求,因为@Pat 正在寻找一个内置函数,但它仍然是一个有趣的库,并且它不会修改 Object.prototype
2021-04-14 06:58:38

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

var keys = [];
for (var k in h)keys.push(k);
最好使用它,而不是“弄乱”Object.prototype。如果我们向 Object.prototype 添加东西,似乎一切都会中断:循环遍历数组/对象的键是一种非常常见的习惯用法。
2021-03-21 06:58:38
当 Object.prototype 被弄乱时,这也不起作用。
2021-04-01 06:58:38