获取JavaScript对象的键列表

329
我有一个类似以下的JavaScript对象:
var obj = {
   key1: 'value1',
   key2: 'value2',
   key3: 'value3',
   key4: 'value4'
}

我怎样才能获得这个对象的键列表和长度?


1
可能是获取JSON对象中属性名称的重复问题。 - T J
1
@TJ 我认为这两者并不完全相同。 这是一个对象,而副本是一个JSON对象。 - GuyT
如果你有下划线,那么只需使用_.keys(your_object)。 - MinhajulAnwar
1
随着时间的推移,自2010年以来情况已经发生了变化,因此最好接受得到最多赞的答案作为“答案”。 - Jonas Wilms
19个回答

666

var obj = {
   key1: 'value1',
   key2: 'value2',
   key3: 'value3',
   key4: 'value4'
}
var keys = Object.keys(obj);
console.log('obj contains ' + keys.length + ' keys: '+  keys);

现在大多数主流浏览器都支持它。


7
它可以在 Chrome 中运行的事实意味着它也可以在 Node.js 上运行,因为两者都构建在 V8 JavaScript 引擎之上。 - Homme Zwaagstra
9
现在是这样,两年前则不是那么多。 - AlbertEngelB
4
请注意,这与 for(key in ob) 不同!Object.keys 不会列出原型链上的键,但 .. in obj 会。 - Albert
9
Windows 7自带IE8。虽然这样做很好,但在人们停止使用IE8之前,这不可能成为被接受的答案。 - snuggles
1
在这里 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/keys,您可以找到一个JavaScript方法,它可以在旧浏览器中正常工作,并且不会覆盖新浏览器中的功能。另外,请查看我的下面的答案。 - Sandro
显示剩余3条评论

358

var obj = {
  key1: 'value1',
  key2: 'value2',
  key3: 'value3',
  key4: 'value4'
};
var keys = [];

for (var k in obj) keys.push(k);

console.log("total " + keys.length + " keys: " + keys);


我不认为Javascript像PHP一样,你可以完全跳过第一行吧?无论如何,这样做也是不可取的。 - Bart van Heukelom
@Bart:不,JavaScript中第一行是必要的。 - Daniel Vassallo
6
请看下面 David Morrissey 的评论,针对这种特殊情况,有时采取这种方法会导致原型中不需要的成员出现在“keys”中。 - user18015
2
@pat:如果你正在使用对象字面量,那只会发生在你扩展 Object.prototype 的情况下,而你本来就不应该这样做。但对于自定义的构造函数,你是正确的。 - Sasha Chedygov
@BartvanHeukelom 即使在2010年6月,这也会引起注意,因为它意味着您隐式地对对象进行了类型定义。将[](或当时的array())分配给它会使其成为一个数组,您可以安全地将其用作数组。 - Niels Keurentjes
@Bart,PHP 标识符有一个丑陋的 []= 运算符,但是在 JavaScript 中,当你执行 myUndefinedVar.push 时,你正在尝试从类型为 'undefined' 的对象中检索属性 push,这会导致引用错误;请注意,我甚至还没有输入 push 后面的括号和参数。 - Rivenfall

27

Underscore.js 让转换变得非常干净:

var keys = _.map(x, function(v, k) { return k; });

编辑:我错过了你也可以这样做:

var keys = _.keys(x);

没错,实际的下划线源码是这样的:nativeKeys = Object.keys; hasOwnProperty = ObjProto.hasOwnProperty; _.has = function(obj, key) { return hasOwnProperty.call(obj, key); }; .keys = nativeKeys || function(obj) { if (obj !== Object(obj)) throw new TypeError('无效对象'); var keys = []; for (var key in obj) if (.has(obj, key)) keys.push(key); return keys; }; - Miguel Alejandro Fuentes Lopez

19
如果你只想要那些特定于某个对象的键而不是任何派生的prototype属性:
function getKeys(obj) {
    var r = []
    for (var k in obj) {
        if (!obj.hasOwnProperty(k)) 
            continue
        r.push(k)
    }
    return r
}

e.g:

var keys = getKeys({'eggs': null, 'spam': true})
var length = keys.length // access the `length` property as usual for arrays

4

首先,Anurags的回答基本上是正确的。但是为了支持所有浏览器版本,您可以使用下面的代码来支持Object.keys(obj),该代码摘自https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys。该代码会在浏览器不支持Object.keys(obj)的情况下添加这个方法。

if (!Object.keys) {
 Object.keys = (function() {
 'use strict';
 var hasOwnProperty = Object.prototype.hasOwnProperty,
    hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
    dontEnums = [
      'toString',
      'toLocaleString',
      'valueOf',
      'hasOwnProperty',
      'isPrototypeOf',
      'propertyIsEnumerable',
      'constructor'
    ],
    dontEnumsLength = dontEnums.length;

return function(obj) {
  if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
    throw new TypeError('Object.keys called on non-object');
  }

  var result = [], prop, i;

  for (prop in obj) {
    if (hasOwnProperty.call(obj, prop)) {
      result.push(prop);
    }
  }

  if (hasDontEnumBug) {
    for (i = 0; i < dontEnumsLength; i++) {
      if (hasOwnProperty.call(obj, dontEnums[i])) {
        result.push(dontEnums[i]);
      }
    }
  }
  return result;
};
}());
}

4
obj = {'a':'c','b':'d'}

您可以尝试:
[index for (index in obj)] 

这将返回:

['a','b']

获取密钥列表 或
[obj[index] for (index in obj)]

获取数值


在Google Chrome v16.0.912.75中无法工作,但在Firefox v10.0中可以工作。 - RobM

4
var keys = new Array();
for(var key in obj)
{
   keys[keys.length] = key;
}

var keyLength = keys.length;

要从对象中访问任何值,您可以使用obj[key];


你需要增加数组索引。 - Vivek
数组索引会自动增加keys.length,每次迭代都不同,因为每次迭代都会插入一个值。 - KrekkieD

4

4

现代浏览器支持:

var obj = {
   key1: 'value1',
   key2: 'value2',
   key3: 'value3',
   key4: 'value4'
}
console.log(Object.keys(obj));
// we can also get values
console.log(Object.values(obj));


3

对于支持 ECMAScript 5 的浏览器,可以使用递归解决方案:

var getObjectKeys = function(obj) {
    var keys = Object.keys(obj);
    var length = keys.length;

    if (length !== 0) {
        for (var i = 0; i < length; i++) {
            if (typeof obj[keys[i]] === 'object') {
                keys[keys[i]] = getObjectKeys(obj[keys[i]]);
            }
        }
    }

    return keys;
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接