计算对象的键/财产数的最快方法是什么?是否可以在不迭代对象的情况下执行此操作?即,不做:
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左右,这个属性被删除了。)
当前回答
对于项目中有ExtJS 4的用户,您可以执行以下操作:
Ext.Object.getSize(myobj);
这样做的优点是它可以在所有兼容ExtJS的浏览器上工作(包括InternetExplorer6和InternetExplorer8)。然而,我认为运行时间并不比O(n)好,正如其他建议的解决方案一样。
其他回答
对于项目中包含Undercore.js的用户,您可以执行以下操作:
_({a:'', b:''}).size() // => 2
或功能风格:
_.size({a:'', b:''}) // => 2
您可以使用以下代码:
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;
如果您真的遇到了性能问题,我建议使用一个函数包装在对象中添加/删除财产的调用,该函数还可以增加/减少适当命名的(size?)属性。
您只需计算一次财产的初始数量,然后再继续。如果没有实际的性能问题,就不用麻烦了。只需将这段代码包装在getNumberOfProperties(对象)函数中,然后使用它即可。
来自Object.defineProperty():
Object.defineProperty(obj、prop、描述符)
您可以将其添加到所有对象:
Object.defineProperty(Object.prototype, "length", {
enumerable: false,
get: function() {
return Object.keys(this).length;
}
});
或单个对象:
var myObj = {};
Object.defineProperty(myObj, "length", {
enumerable: false,
get: function() {
return Object.keys(this).length;
}
});
例子:
var myObj = {};
myObj.name = "John Doe";
myObj.email = "leaked@example.com";
myObj.length; // Output: 2
通过这种方式添加,它不会在中显示。。在循环中:
for(var i in myObj) {
console.log(i + ": " + myObj[i]);
}
输出:
name: John Doe
email: leaked@example.com
注意:它在Internet Explorer 9之前的浏览器中不起作用。
以下是三种方法的一些性能测试;
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跟踪自己的大小,所以我们只返回一个数字字段。它比任何其他方法都快得多。如果可以控制对象,请将其转换为贴图。