【问题标题】:Get array of object's keys获取对象键的数组
【发布时间】:2012-02-04 11:52:25
【问题描述】:

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

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

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

【问题讨论】:

  • 除了添加if(foo.hasOwnProperty(key)),这就是我要做的。或者,使用$.map
  • 哦,对于 Python 风格的单线,虽然...
  • 一个老问题,所以不值得一个完整的答案,但对于那些想要摆弄的人来说......jsfiddle.net/LR5D9/3这个解决方案处理了原型声明搞砸for var in x循环的问题
  • @unsynchronized 请不要将解决方案发布为 cmets。您的评论故意违反了清晰且有意的页面结构设计。

标签: javascript ecmascript-5


【解决方案1】:

使用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 特性。这意味着它适用于所有现代浏览器,但 will not work in legacy browsers.

ES5-shim 有一个implementation of Object.keys you can steal

【讨论】:

  • 注意:这只适用于现代浏览器(我的意思是不是 IE
  • 那么移动浏览器呢?
  • @SmartyTwiti:我不确定。我假设它像 Chrome 或 Firefox 一样。
  • MDN 也有上面提到的 Polyfill,但注意到 IE7 和可能 8 中的错误,然后在此处引用更短的 Polyfill:tokenposts.blogspot.com.au/2012/04/…
  • 在我意识到这是一个静态类方法之前,我尝试将键作为实例的属性调用的次数......对 api 的理解--
【解决方案2】:

你可以使用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 */});
【解决方案3】:

当然,Object.keys() 是获取对象键的最佳方法。如果它在您的环境中不可用,则可以使用示例中的代码轻松填充(除非您需要考虑到您的循环将遍历原型链上的所有属性,不像Object.keys() 的行为)。

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

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

jsFiddle.

...可以修改。您可以在 variable 部分进行赋值。

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

jsFiddle.

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

【讨论】:

  • 我喜欢这个var keys = [], i = 0; for (keys[i++] in foo) {} +1
  • 听说“for in”不保证顺序,不知道Object.keys有没有?
  • @ChrisStephens 都不保证顺序,即使键最终位于有序数组中。
  • 所有这些解决方案都需要hasOwnProperty() 检查,确定吗?
  • @TIMINeutron 没有理由不应该这样做:)
【解决方案4】:

如果您在这里寻找将 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 }}}))

【讨论】:

    【解决方案5】:

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

    var keys = (function(o){var ks=[]; for(var k in o) ks.push(k); return ks})(foo);
    

    【讨论】:

    • 也许应该是var enumerableKeysOnThePrototypeChain ;)
    • 也许我们足够聪明,知道如果对象完全在我们的权限范围内创建而不是从其他地方导入,我们不必担心 hasOwnProperty
    • 虽然不像 @alex 的第二个答案 (for (keys[i++] in foo) {}) 那样 Pythonic,因为您仍在执行 Array.push()(更不用说声明整个函数)。 pythonic 实现应该尽可能多地依赖隐式理解,如果失败,则使用 lambda 表达式。
    【解决方案6】:

    总结

    要获取对象的所有键,您可以使用Object.keys()Object.keys() 接受一个对象作为参数并返回一个包含所有键的数组。

    示例:

    const object = {
      a: 'string1',
      b: 42,
      c: 34
    };
    
    const keys = Object.keys(object)
    
    console.log(keys);
    
    console.log(keys.length) // we can easily access the total amount of properties the object has

    在上面的示例中,我们将一个键数组存储在键 const 中。然后,我们可以通过检查键数组的长度轻松访问对象的属性数量。

    获取值:Object.values()

    Object.keys() 的互补功能是Object.values()。该函数接受一个对象作为参数并返回一个值数组。例如:

    const object = {
      a: 'random',
      b: 22,
      c: true
    };
    
    
    console.log(Object.values(object));

    【讨论】:

      【解决方案7】:

      如果你决定使用 Underscore.js,你最好这样做

      var foo = { 'alpha' : 'puffin', 'beta' : 'beagle' };
      var keys = [];
      _.each( foo, function( val, key ) {
          keys.push(key);
      });
      console.log(keys);
      

      【讨论】:

      • 为什么?解释是什么?
      【解决方案8】:

      到了 2022 年,JavaScript 仍然没有可靠的方法来处理哈希?

      这会发出警告但有效:

      Object.prototype.keys = function() { return Object.keys(this) }
      console.log("Keys of an object: ", { a:1, b:2 }.keys() )
      
      // Keys of an object:  Array [ "a", "b" ]
      // WARN: Line 8:1:  Object prototype is read only, properties should not be added  no-extend-native
      

      也就是说,Extending Built-in Objects is Controversial

      【讨论】:

        猜你喜欢
        • 2021-06-30
        • 1970-01-01
        • 2020-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多