计算对象的键/财产数的最快方法是什么?是否可以在不迭代对象的情况下执行此操作?即,不做:

var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) ++count;

(Firefox确实提供了一个神奇的__count__属性,但在版本4左右,这个属性被删除了。)


当前回答

如Avi Flax所述,

Object.keys(obj).length

将对对象上的所有可枚举财产执行此操作,但要同时包含非可枚举财产,您可以改用object.getOwnPropertyNames。区别如下:

var myObject = new Object();

Object.defineProperty(myObject, "nonEnumerableProp", {
  enumerable: false
});
Object.defineProperty(myObject, "enumerableProp", {
  enumerable: true
});

console.log(Object.getOwnPropertyNames(myObject).length); //outputs 2
console.log(Object.keys(myObject).length); //outputs 1

console.log(myObject.hasOwnProperty("nonEnumerableProp")); //outputs true
console.log(myObject.hasOwnProperty("enumerableProp")); //outputs true

console.log("nonEnumerableProp" in myObject); //outputs true
console.log("enumerableProp" in myObject); //outputs true

如这里所述,这与Object.keys具有相同的浏览器支持。

然而,在大多数情况下,您可能不希望在这些类型的操作中包含非数值,但了解它们的区别总是很好的;)

其他回答

您可以使用以下代码:

if (!Object.keys) {
    Object.keys = function (obj) {
        var keys = [],
            k;
        for (k in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, k)) {
                keys.push(k);
            }
        }
        return keys;
    };
}

然后,您也可以在较旧的浏览器中使用此功能:

var len = Object.keys(obj).length;

要在任何ES5兼容环境中执行此操作,如Node.js、Chrome、Internet Explorer 9+、Firefox 4+或Safari 5+:

Object.keys(obj).length

浏览器兼容性Object.keys文档(包括可以添加到非ES5浏览器的方法)

要迭代AviFlax的答案,Object.keys(obj).length对于没有绑定函数的对象是正确的。

例子:

obj = {"lol": "what", owo: "pfft"};
Object.keys(obj).length; // should be 2

arr = [];
obj = {"lol": "what", owo: "pfft"};
obj.omg = function(){
    _.each(obj, function(a){
        arr.push(a);
    });
};
Object.keys(obj).length; // should be 3 because it looks like this
/* obj === {"lol": "what", owo: "pfft", omg: function(){_.each(obj, function(a){arr.push(a);});}} */

避免这种情况的步骤:

不要将函数放在要计算键数的对象中使用单独的对象或专门为函数创建新对象(如果要使用object.keys(obj).length计算文件中有多少个函数)

另外,是的,我在示例中使用了Node.js中的_或Undercore.js模块。

文档可以在这里找到,也可以在GitHub和其他各种信息上找到。

最后是一个lodash实现https://lodash.com/docs#size

_.size(对象)

如Avi Flax所述,

Object.keys(obj).length

将对对象上的所有可枚举财产执行此操作,但要同时包含非可枚举财产,您可以改用object.getOwnPropertyNames。区别如下:

var myObject = new Object();

Object.defineProperty(myObject, "nonEnumerableProp", {
  enumerable: false
});
Object.defineProperty(myObject, "enumerableProp", {
  enumerable: true
});

console.log(Object.getOwnPropertyNames(myObject).length); //outputs 2
console.log(Object.keys(myObject).length); //outputs 1

console.log(myObject.hasOwnProperty("nonEnumerableProp")); //outputs true
console.log(myObject.hasOwnProperty("enumerableProp")); //outputs true

console.log("nonEnumerableProp" in myObject); //outputs true
console.log("enumerableProp" in myObject); //outputs true

如这里所述,这与Object.keys具有相同的浏览器支持。

然而,在大多数情况下,您可能不希望在这些类型的操作中包含非数值,但了解它们的区别总是很好的;)

如前一个答案中所回答的:Object.keys(obj).length

但是:因为我们现在在ES6中有一个真正的Map类,所以我建议使用它,而不是使用对象的财产。

const map = new Map();
map.set("key", "value");
map.size; // THE fastest way