计算对象的键/属性数的最快方法是什么?它可以在不迭代对象的情况下执行此操作吗?即没有做
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兼容的环境中执行此操作,例如 节点,Chrome,IE 9 +,FF 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 您可以使用 _。尺寸 (感谢@douwe):
_.size(obj)
或者你也可以使用 _.keys 对某些人来说可能更清楚:
_.keys(obj).length
我强烈推荐使用Underscore,它是一个用于执行大量基本操作的紧凑库。它们尽可能匹配ECMA5并遵循本机实现。
否则我支持@ Avi的答案。我编辑它以添加指向MDC文档的链接,其中包含可以添加到非ECMA5浏览器的keys()方法。
标准的Object实现(ES5.1对象内部属性和方法)不需要 Object
跟踪其键/属性的数量,因此应该没有标准的方法来确定一个大小 Object
没有显式或隐式迭代其键。
所以这里是最常用的替代品:
Object.keys(obj).length;
作品 国内 迭代键以计算临时数组并返回其长度。
本主题其他地方的许多基于库的示例在其库的上下文中都是有用的习惯用法。然而,从性能的角度来看,与完美的无库代码相比没有任何好处,因为所有这些库方法实际上都封装了for-loop或ES5 Object.keys
(原生的或shimmed)。
该 最慢的部分 这种for循环通常是 .hasOwnProperty()
调用,因为函数调用开销。所以,当我只想要一个JSON对象的条目数时,我就跳过了 .hasOwnProperty()
如果我知道没有代码也没有扩展,请致电 Object.prototype
。
否则,您的代码可以通过制作进行非常轻微的优化 k
当地的(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;
在给定环境中这是否更快是基准测试的问题。无论如何,可以预期非常有限的性能增益。
如果您实际遇到性能问题,我建议使用一个函数来包装调用向对象添加/删除属性的调用,该函数也会增加/减少适当命名的(size?)属性。
您只需计算一次属性的初始数量,然后从那里继续。如果没有实际的性能问题,请不要打扰。只需在函数中包含该位代码即可 getNumberOfProperties(object)
并完成它。
我不知道有任何方法可以做到这一点,但是为了尽量减少迭代,你可以尝试检查是否存在 __count__
如果它不存在(即不是Firefox),那么你可以迭代对象并定义它以供以后使用,例如:
if (myobj.__count__ === undefined) {
myobj.__count__ = ...
}
这种方式支持任何浏览器 __count__
会使用它,并且只会对那些没有进行迭代。如果计数发生变化而您无法执行此操作,则可以始终将其设为一个函数:
if (myobj.__count__ === undefined) {
myobj.__count__ = function() { return ... }
myobj.__count__.toString = function() { return this(); }
}
这样你随时可以参考myobj。__count__
该函数将触发并重新计算。
正如Avi Flax所述 https://stackoverflow.com/a/4889658/1047014
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
但是,在大多数情况下,您可能不希望在这些类型的操作中包含非枚举,但了解差异总是很好;)