计算对象的键/属性数量的最快方法是什么?是否可以在不迭代对象的情况下执行此操作?即,不做:
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 左右被删除了。)
要在任何ES5兼容环境中执行此操作,例如Node.js、Chrome、Internet Explorer 9+、Firefox 4+ 或 Safari 5+:
Object.keys(obj).length
您可以使用此代码:
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;
如果你正在使用Underscore.js可以使用_.size(感谢杜威·):
_.size(obj)
或者,您也可以使用_.keys,这对某些人来说可能更清楚:
_.keys(obj).length
我强烈推荐 Underscore.js。这是一个紧凑的库,可以做很多基本的事情。只要有可能,它们就会匹配ECMAScript 5并遵循本机实现。
否则我支持Avi Flax 的回答。我对其进行了编辑以添加指向MDC文档的链接,其中包含可以添加到非 ECMAScript 5 浏览器的 keys() 方法。
标准对象实现(ES5.1 对象内部属性和方法)不需要 anObject
来跟踪其键/属性的数量,因此应该没有标准方法来确定 an 的大小Object
而不显式或隐式迭代其键。
所以这里是最常用的替代方案:
Object.keys(obj).length;
通过内部迭代键来计算临时数组并返回其长度。
本主题其他地方的许多基于库的示例在其库的上下文中都是有用的习语。然而,从性能的角度来看,与完美的无库代码相比,没有任何好处,因为所有这些库方法实际上都封装了 for 循环或 ES5 Object.keys
(原生或填充)。
的最慢的部分这样的的for循环一般是.hasOwnProperty()
呼叫,因为该函数调用开销。因此,当我只想要 JSON 对象的条目数时,.hasOwnProperty()
如果我知道没有代码也不会扩展 Object.prototype
.
否则,您的代码可以通过创建k
local ( var k
) 和使用前缀增量运算符 ( ++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;
在给定的环境中这是否更快是一个基准测试的问题。无论如何,可以预期的性能增益非常有限。
以下是对三种方法的一些性能测试;
https://jsperf.com/get-the-number-of-keys-in-an-object
每秒 20,735 次操作
它非常简单和兼容,运行速度快但价格昂贵,因为它创建了一个新的键数组,然后被丢弃。
return Object.keys(objectToRead).length;
每秒 15,734 次操作
let size=0;
for(let k in objectToRead) {
size++
}
return size;
它稍慢,但远不及内存使用量,因此如果您有兴趣针对移动设备或其他小型机器进行优化,它可能会更好。
每秒 953,839,338 次操作
return mapToRead.size;
基本上,Map 跟踪它自己的大小,所以我们只是返回一个数字字段。它比任何其他方法都快得多。如果您可以控制对象,请将它们转换为贴图。