mjs*_*mjs 1452 javascript performance properties key count
计算对象的键/属性数的最快方法是什么?它可以在不迭代对象的情况下完成此操作吗?即没有做
var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) count++;
Run Code Online (Sandbox Code Playgroud)
(Firefox确实提供了一个神奇的__count__属性,但是在版本4的某个地方删除了它.)
Avi*_*lax 2377
要做到这一点__CODE__,比如__CODE__
Object.keys(obj).length
Run Code Online (Sandbox Code Playgroud)
__CODE__浏览器的方法)Ren*_*nck 150
你可以使用这段代码:
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;
};
}
Run Code Online (Sandbox Code Playgroud)
然后您也可以在旧版浏览器中使用它:
var len = Object.keys(obj).length;
Run Code Online (Sandbox Code Playgroud)
stu*_*eek 134
如果你正在使用Underscore.js可以使用_.size(感谢@douwe):
_.size(obj)
或者你也可以使用_.keys,这对某些人来说可能更清楚:
_.keys(obj).length
我强烈推荐使用Underscore,它是一个用于执行大量基本操作的紧凑库.只要有可能,它们就会匹配ECMA5并遵循本机实现.
否则我支持@ Avi的答案.我编辑它以添加指向MDC文档的链接,其中包含可以添加到非ECMA5浏览器的keys()方法.
Luc*_*125 75
标准的Object实现(ES5.1对象内部属性和方法)不需要Object跟踪其键/属性的数量,因此没有标准方法来确定a的大小Object而不显式或隐式地迭代其键.
所以这里是最常用的替代品:
Object.keys(obj).length;通过内部迭代键来计算临时数组并返回其长度.
本主题其他地方的许多基于库的示例在其库的上下文中都是有用的习惯用法.然而,从性能的角度来看,与完美的无库代码相比没有任何好处,因为所有这些库方法实际上都封装了for-loop或ES5 Object.keys(native或shimmed).
这种for循环的最慢部分通常是.hasOwnProperty()调用,因为函数调用开销.因此,当我只想要JSON对象的条目数时,.hasOwnProperty()如果我知道没有代码也没有扩展,我就跳过调用 Object.prototype.
否则,通过使用klocal(var k)和使用prefix-increment operator(++count)而不是postfix ,可以非常轻微地优化您的代码.
var count = 0;
for (var k in myobj) if (myobj.hasOwnProperty(k)) ++count;
Run Code Online (Sandbox Code Playgroud)
另一个想法依赖于缓存hasOwnProperty方法:
var hasOwn = Object.prototype.hasOwnProperty;
var count = 0;
for (var k in myobj) if (hasOwn.call(myobj, k)) ++count;
Run Code Online (Sandbox Code Playgroud)
在给定环境中这是否更快是基准测试的问题.无论如何,可以预期非常有限的性能增益.
daz*_*act 30
这适用于数组和对象
//count objects/arrays
function count(obj){
return Object.keys(obj).length
}
Run Code Online (Sandbox Code Playgroud)
使用循环对对象/数组进行计数
function count(obj){
var x=0;
for(k in obj){
x++;
}
return x;
}
Run Code Online (Sandbox Code Playgroud)
计算对象/数组或字符串的长度
function count(obj){
if (typeof (obj) === 'string' || obj instanceof String)
{
return obj.toString().length;
}
return Object.keys(obj).length
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*per 28
以下是对三种方法的一些性能测试;
https://jsperf.com/get-the-number-of-keys-in-an-object
每秒 20,735 次操作
它非常简单和兼容,运行速度快但价格昂贵,因为它创建了一个新的键数组,然后被丢弃。
return Object.keys(objectToRead).length;
Run Code Online (Sandbox Code Playgroud)
每秒 15,734 次操作
let size=0;
for(let k in objectToRead) {
size++
}
return size;
Run Code Online (Sandbox Code Playgroud)
它稍慢,但远不及内存使用量,因此如果您有兴趣针对移动设备或其他小型机器进行优化,它可能会更好。
每秒 953,839,338 次操作
return mapToRead.size;
Run Code Online (Sandbox Code Playgroud)
基本上,Map 跟踪它自己的大小,所以我们只是返回一个数字字段。它比任何其他方法都快得多。如果您可以控制对象,请将它们转换为贴图。
Con*_*ion 26
如果您实际遇到性能问题,我建议使用一个函数来包装调用向对象添加/删除属性的调用,该函数也会增加/减少一个适当命名的(size?)属性.
您只需要计算一次属性的初始数量,然后从那里继续.如果没有实际的性能问题,请不要打扰.只需在函数中包含该位代码即可getNumberOfProperties(object)完成.
Luk*_*ett 15
我不知道有任何方法可以做到这一点,但是为了将迭代保持在最低限度,您可以尝试检查__count__是否存在(如果它不存在)(即不是Firefox),那么您可以迭代对象并定义它供以后使用,例如:
if (myobj.__count__ === undefined) {
myobj.__count__ = ...
}
Run Code Online (Sandbox Code Playgroud)
这样任何支持的浏览器__count__都会使用它,并且只对那些不支持的浏览器执行迭代.如果计数发生变化而您无法执行此操作,则可以始终将其设为一个函数:
if (myobj.__count__ === undefined) {
myobj.__count__ = function() { return ... }
myobj.__count__.toString = function() { return this(); }
}
Run Code Online (Sandbox Code Playgroud)
这样你随时可以参考myobj.__count__该函数将触发并重新计算.
Ben*_*der 15
如Avi Flax所述/sf/answers/342276091/
Object.keys(obj).length
Run Code Online (Sandbox Code Playgroud)
将为您的对象上的所有可枚举属性执行操作,但也包括您可以使用的非可枚举属性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
Run Code Online (Sandbox Code Playgroud)
如上所述,这与浏览器支持相同Object.keys
但是,在大多数情况下,您可能不希望在这些类型的操作中包含非枚举,但了解差异总是很好;)
Bel*_*ndu 13
迭代Avi Flax回答Object.keys(obj).length对于没有与之关联的函数的对象是正确的
例:
obj = {"lol": "what", owo: "pfft"};
Object.keys(obj).length; // should be 2
Run Code Online (Sandbox Code Playgroud)
与
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);});}} */
Run Code Online (Sandbox Code Playgroud)
避免这种情况的步骤:
不要将函数放在要计算键数的对象中
使用单独的对象或专门为函数创建一个新对象(如果你想计算文件中有多少函数使用Object.keys(obj).length)
也是的,我在我的例子中使用了nodejs的_或下划线模块
文档可以在http://underscorejs.org/找到,以及它在github上的来源和各种其他信息
最后是一个lodash实现https://lodash.com/docs#size
_.size(obj)
Fla*_*ken 10
如以上回答: Object.keys(obj).length
但是:正如我们现在在ES6中拥有一个真正的Map类一样,我建议使用它而不是使用对象的属性。
const map = new Map();
map.set("key", "value");
map.size; // THE fastest way
Run Code Online (Sandbox Code Playgroud)
对于那些在项目中包含Underscore.js的人,您可以:
_({a:'', b:''}).size() // => 2
Run Code Online (Sandbox Code Playgroud)
或功能风格:
_.size({a:'', b:''}) // => 2
Run Code Online (Sandbox Code Playgroud)
来自:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
Object.defineProperty(obj,prop,descriptor)
您可以将其添加到所有对象:
Object.defineProperty(Object.prototype, "length", {
enumerable: false,
get: function() {
return Object.keys(this).length;
}
});
Run Code Online (Sandbox Code Playgroud)
或者单个对象:
var myObj = {};
Object.defineProperty(myObj, "length", {
enumerable: false,
get: function() {
return Object.keys(this).length;
}
});
Run Code Online (Sandbox Code Playgroud)
例:
var myObj = {};
myObj.name = "John Doe";
myObj.email = "leaked@example.com";
myObj.length; //output: 2
Run Code Online (Sandbox Code Playgroud)
添加这种方式,它不会显示在for..in循环中:
for(var i in myObj) {
console.log(i + ":" + myObj[i]);
}
Run Code Online (Sandbox Code Playgroud)
输出:
name:John Doe
email:leaked@example.com
Run Code Online (Sandbox Code Playgroud)
注意:它在<IE9浏览器中不起作用.
我如何解决这个问题是建立我自己的基本列表实现,它记录了对象中存储了多少项.它非常简单.像这样的东西:
function BasicList()
{
var items = {};
this.count = 0;
this.add = function(index, item)
{
items[index] = item;
this.count++;
}
this.remove = function (index)
{
delete items[index];
this.count--;
}
this.get = function(index)
{
if (undefined === index)
return items;
else
return items[index];
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
623679 次 |
| 最近记录: |