计算对象的键/财产数的最快方法是什么?是否可以在不迭代对象的情况下执行此操作?即,不做:
var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) ++count;
(Firefox确实提供了一个神奇的__count__属性,但在版本4左右,这个属性被删除了。)
计算对象的键/财产数的最快方法是什么?是否可以在不迭代对象的情况下执行此操作?即,不做:
var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) ++count;
(Firefox确实提供了一个神奇的__count__属性,但在版本4左右,这个属性被删除了。)
当前回答
如果您真的遇到了性能问题,我建议使用一个函数包装在对象中添加/删除财产的调用,该函数还可以增加/减少适当命名的(size?)属性。
您只需计算一次财产的初始数量,然后再继续。如果没有实际的性能问题,就不用麻烦了。只需将这段代码包装在getNumberOfProperties(对象)函数中,然后使用它即可。
其他回答
以下是三种方法的一些性能测试;
https://jsperf.com/get-the-number-of-keys-in-an-object
对象.keys().length
每秒20735次操作
它非常简单和兼容,运行速度快但成本高昂,因为它创建了一个新的密钥数组,然后将其丢弃。
return Object.keys(objectToRead).length;
循环键
每秒15734次操作
let size=0;
for(let k in objectToRead) {
size++
}
return size;
它稍微慢一点,但与内存使用量相差甚远,因此如果您对移动或其他小型机器的优化感兴趣,它可能会更好。
使用贴图而不是对象
每秒953839338次操作
return mapToRead.size;
基本上,Map跟踪自己的大小,所以我们只返回一个数字字段。它比任何其他方法都快得多。如果可以控制对象,请将其转换为贴图。
如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实现(ES5.1对象内部财产和方法)不要求Object跟踪其键/财产的数量,因此在不显式或隐式迭代其键的情况下,应该没有标准的方法来确定Object的大小。
以下是最常用的替代方案:
1.ECMAScript的Object.keys()
对象.键(obj).长度;通过内部迭代键来计算临时数组并返回其长度。
优点-可读和干净的语法。如果本机支持不可用,则不需要库或自定义代码,除非使用垫片Cons—由于创建阵列而产生的内存开销。
2.基于库的解决方案
本主题其他地方的许多基于库的示例在其库的上下文中都是有用的习惯用法。然而,从性能的角度来看,与完美的无库代码相比,没有什么可获得的,因为所有这些库方法实际上都封装了for循环或ES5 Object.keys(原生或填充)。
3.优化for循环
由于函数调用开销,这种for循环最慢的部分通常是.hasOwnProperty()调用。因此,当我只需要一个JSON对象的条目数时,如果我知道没有代码也不会扩展object.prototype,我就跳过.hasOwnProperty()调用。
否则,通过使k为本地(vark),并使用前缀递增运算符(++count)而不是后缀,可以稍微优化代码。
var count = 0;
for (var k in myobj) if (myobj.hasOwnProperty(k)) ++count;
另一个想法依赖于缓存hasOwnProperty方法:
var hasOwn = Object.prototype.hasOwnProperty;
var count = 0;
for (var k in myobj) if (hasOwn.call(myobj, k)) ++count;
在给定的环境中,这是否更快是一个基准测试的问题。无论如何,预期的性能增益非常有限。
您可以使用:
Object.keys(objectName).length;
and
Object.values(objectName).length;
要在任何ES5兼容环境中执行此操作,如Node.js、Chrome、Internet Explorer 9+、Firefox 4+或Safari 5+:
Object.keys(obj).length
浏览器兼容性Object.keys文档(包括可以添加到非ES5浏览器的方法)