获取对象的键数组

IT技术 javascript ecmascript-5
2021-02-07 18:52:21

我想以数组的形式获取 JavaScript 对象的键,无论是在 jQuery 还是纯 JavaScript 中。

还有比这更简洁的方法吗?

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
    keys.push(key);
}
6个回答

使用Object.keys

var foo = {
  'alpha': 'puffin',
  'beta': 'beagle'
};

var keys = Object.keys(foo);
console.log(keys) // ['alpha', 'beta'] 
// (or maybe some other order, keys are unordered).

这是 ES5 的特性。这意味着它适用于所有现代浏览器,但不适用于旧版浏览器

ES5-shim 有一个你可以窃取实现Object.keys

那么移动浏览器呢?
2021-03-13 18:52:21
在我意识到它是一个静态类方法之前,我尝试将键作为实例的属性调用的次数......对api的理解--
2021-03-13 18:52:21
@SmartyTwiti:我不确定。我假设它像 Chrome 或 Firefox 一样。
2021-03-15 18:52:21
MDN 也有上面提到的 Polyfill,但注意到了 IE7 和 8 中的错误,然后在这里引用了一个更短的 Polyfill:tokenposts.blogspot.com.au/2012/04/...
2021-03-18 18:52:21
注意:这仅适用于现代浏览器(我的意思是不适用于 IE < 9)。
2021-04-06 18:52:21

您可以使用 jQuery 的$.map.

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' },
keys = $.map(foo, function(v, i){
  return i;
});
或者each,如果您正在与他们一起做某事。$.each(foo, function(index, value){/* do something with index */});
2021-03-17 18:52:21

当然Object.keys()最好的获得一个对象的关键途径。如果它在您的环境中不可用,则可以使用例如您的示例中的代码对其进行微调(除非您需要考虑到您的循环将遍历原型链上的所有属性,这与Object.keys()的行为不同)。

但是,您的示例代码...

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [];
for (var key in foo) {
    keys.push(key);
}

js小提琴

……可以修改。您可以直接在变量部分进行赋值

var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
var keys = [], i = 0;
for (keys[i++] in foo) {}

js小提琴

当然,这种行为与Object.keys()实际行为不同jsFiddle)。您可以简单地使用MDN 文档中shim

我听说“for in”不能保证顺序,你知道 Object.keys 是否可以?
2021-03-10 18:52:21
@TIMINeutron 没有理由不应该:)
2021-03-11 18:52:21
@ChrisStephens 既不保证顺序,即使键最终位于有序数组中。
2021-03-22 18:52:21
所有这些解决方案都需要hasOwnProperty()检查,确定吗?
2021-03-29 18:52:21
我喜欢这个var keys = [], i = 0; for (keys[i++] in foo) {}+1
2021-04-08 18:52:21

如果您在这里寻找将 n 深度嵌套对象的键列为平面数组的内容:

const getObjectKeys = (obj, prefix = '') => {
  return Object.entries(obj).reduce((collector, [key, val]) => {
    const newKeys = [ ...collector, prefix ? `${prefix}.${key}` : key ]
    if (Object.prototype.toString.call(val) === '[object Object]') {
      const newPrefix = prefix ? `${prefix}.${key}` : key
      const otherKeys = getObjectKeys(val, newPrefix)
      return [ ...newKeys, ...otherKeys ]
    }
    return newKeys
  }, [])
}

console.log(getObjectKeys({a: 1, b: 2, c: { d: 3, e: { f: 4 }}}))

我不知道不那么冗长,但我的灵感是通过单行请求将以下内容强制转换为一行,但不知道它是多么 Pythonic ;)

var keys = (function(o){var ks=[]; for(var k in o) ks.push(k); return ks})(foo);
也许那应该是var enumerableKeysOnThePrototypeChain;)
2021-03-17 18:52:21
也许我们足够聪明,知道如果对象完全在我们的权限下创建而不是从其他地方导入,我们就不必担心 hasOwnProperty
2021-03-18 18:52:21
不过,不像@alex 的第二个答案 ( for (keys[i++] in foo) {})那样 Pythonic ,因为您仍在表演Array.push()(更不用说声明整个函数了)。pythonic 实现应该尽可能多地依赖隐式理解,如果失败,则使用 lambda 表达式。
2021-04-06 18:52:21