Answers:
要在任何与ES5兼容的环境(例如Node,Chrome,IE 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;
(Object.prototype.hasOwnProperty.call(obj, k))
什么?
hasOwnProperty
需要检查的原因。它仅返回在对象本身上设置的属性。
obj.hasOwnProperty(k)
(我实际上在原始帖子中做了,但后来进行了更新)。hasOwnProperty
可以在每个对象上使用,因为它是Object
原型的一部分,但是在极少数情况下,该方法将被删除或覆盖,您可能会得到意想不到的结果。通过调用它Object.prototype
可以使它更健壮。使用的原因call
是因为您要在obj
而不是原型上调用方法。
如果你正在使用Underscore.js可以使用_.size(感谢@douwe):
_.size(obj)
另外,您也可以使用_.keys,对于某些用户可能更清楚:
_.keys(obj).length
我强烈推荐Underscore,它是一个紧凑的库,可以处理很多基本的事情。只要有可能,它们就会与ECMA5相匹配并遵循本机实现。
否则,我支持@Avi的答案。我对其进行了编辑,以添加指向MDC文档的链接,其中包括可以添加到非ECMA5浏览器的keys()方法。
_.keys(obj).length
最适合我,因为我的返回对象有时是一个纯字符串,其中没有属性。_.size(obj)
给我回了字符串的长度,而_.keys(obj).length
返回0
Object.keys
内部使用。for..in
如果Object.keys
未定义,下划线还会将每个键复制到循环内的数组中。
标准的Object实现(ES5.1对象内部属性和方法)不需要Object
跟踪其键/属性的数量,因此,在Object
不显式或隐式迭代其键的情况下,应该没有标准的方法来确定a的大小。
因此,这是最常用的替代方法:
Object.keys(obj).length;
通过内部遍历键以计算临时数组并返回其长度来工作。
在本主题的其他地方,许多基于库的示例在它们的库上下文中都是有用的成语。但是,从性能的角度来看,与完美的无库代码相比,没有任何收获,因为所有这些库方法实际上都封装了for循环或ES5 Object.keys
(本机或填充)。
的最慢的部分这样的的for循环一般是.hasOwnProperty()
呼叫,因为该函数调用开销。因此,当我只想要JSON对象的条目数时,.hasOwnProperty()
如果我知道没有代码也不会扩展,就跳过该调用 Object.prototype
。
否则,可以通过使用k
local(var k
)和使用前缀增量运算符(++count
)而不是postfix 对代码进行非常小的优化。
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;
在给定的环境下这是否更快,这是基准测试的问题。无论如何,可以预期性能提升非常有限。
var k in myobj
提高性能?据我所知,只有函数在JavaScript中声明新的作用域。循环中是否是此规则的例外?
for (var k in myobj) hasOwn.call(myobj, k) && ++count;
即用简单的&&替换if语句?
Object.getOwnPropertyNames(obj).length
; 简单得多。
如果您实际上遇到了性能问题,建议您使用一个函数来包装向对象添加属性或从对象中删除属性的调用,该函数还要增加/减少适当命名的(size?)属性。
您只需计算一次属性的初始数量,然后从那里继续。如果没有实际的性能问题,请不要打扰。只需将这段代码包装在一个函数中,getNumberOfProperties(object)
然后完成它即可。
正如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
但是,在大多数情况下,您可能不希望在这些类型的操作中包括无数变量,但是了解它们之间的差异总是很好的;)
Object.getOwnPropertyNames
,你是这里唯一的一个……
我不知道有什么方法可以执行此操作,但是为了将迭代次数降到最低,您可以尝试检查是否存在,__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__
该函数将触发并重新计算。
Object.prototype.__count__
在壁虎1.9.3被删除:whereswalden.com/2010/04/06/... 计数 -属性-对象- -是-被移除的/
Object.__count__
消失了,也很好摆脱了。
要在Avi Flax上进行迭代,请回答Object.keys(obj).length对于没有绑定功能的对象是正确的
例:
obj = {"lol": "what", owo: "pfft"};
Object.keys(obj).length; // should be 2
与
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);});}} */
避免这种情况的步骤:
不要将函数放在要计算键数的对象中
使用一个单独的对象或专门为函数创建一个新对象(如果您想使用来计算文件中有多少个函数Object.keys(obj).length
)
同样是的,我在示例中使用了nodejs的_或下划线模块
可以在http://underscorejs.org/上找到文档,以及它在github上的源代码和其他各种信息
最后是lodash实现https://lodash.com/docs#size
_.size(obj)
Array(obj).length
:它不起作用。http://jsfiddle.net/Jhy8M/
false
,虽然我还没有找到如何任何文件var obj = { a: true, b: true }
可以从不同var obj = {}; obj.a = true; obj.b = true;
或干脆如果W3的不同解释/语义学被Chrome浏览器采用。
以下是对三种方法的性能测试;
https://jsperf.com/get-the-number-of-keys-in-an-object
每秒20,735次操作
非常简单且兼容。运行速度快但价格昂贵,因为它会创建一个新的键数组,然后将其丢弃。
return Object.keys(objectToRead).length;
每秒15734次操作
let size=0;
for(let k in objectToRead) {
size++
}
return size;
速度稍慢,但与内存使用量相差无几,如果您有兴趣针对移动或其他小型计算机进行优化,则可能会更好
每秒953,839,338次操作
return mapToRead.size;
基本上,地图会跟踪自己的大小,因此我们只返回一个数字字段。比任何其他方法快得多。如果您可以控制该对象,则可以将其转换为地图。
来自:https : //developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/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..in循环中:
for(var i in myObj) {
console.log(i + ":" + myObj[i]);
}
输出:
name:John Doe
email:leaked@example.com
注意:它在<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];
}
}
var i = basiclist.count
while(i--){...}
add
替换旧项目或是否remove
用不存在的索引调用。另外,如果列表undefined
有效,则无法检查列表是否具有给定的索引。
我尝试使它可用于所有这样的对象:
Object.defineProperty(Object.prototype, "length", {
get() {
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;
};
}
return Object.keys(this).length;
},});
console.log({"Name":"Joe","Age":26}.length) //returns 2
Google Closure为此提供了很好的功能... goog.object.getCount(obj)