Length of a JavaScript object
如果我有一个javascript对象,比如
1 2 3 4 | var myObject = new Object(); myObject["firstname"] ="Gareth"; myObject["lastname"] ="Simpson"; myObject["age"] = 21; |
是否有内置或公认的最佳实践方法来获取此对象的长度?
最有力的答案(即捕捉到您在导致最少错误的同时尝试做的事情的意图)是:
1 2 3 4 5 6 7 8 9 10 | Object.size = function(obj) { var size = 0, key; for (key in obj) { if (obj.hasOwnProperty(key)) size++; } return size; }; // Get the size of an object var size = Object.size(myArray); |
在javascript中有一种约定,您不能向object.prototype添加内容,因为它可以破坏各种库中的枚举。不过,向对象添加方法通常是安全的。
以下是截至2016年的最新消息,以及ES5及以后的广泛部署。对于IE9+和所有其他支持ES5+的现代浏览器,您可以使用
1 | var size = Object.keys(myObj).length; |
这不需要修改任何现有的原型,因为
编辑:对象可以具有不能通过object.key方法返回的符号属性。因此,如果不提及它们,答案将是不完整的。
符号类型已添加到语言中,以创建对象属性的唯一标识符。符号类型的主要好处是防止覆盖。
1 2 3 4 5 6 7 8 9 10 11 | var person = { [Symbol('name')]: 'John Doe', [Symbol('age')]: 33, "occupation":"Programmer" }; const propOwn = Object.getOwnPropertyNames(person); console.log(propOwn.length); // 1 let propSymb = Object.getOwnPropertySymbols(person); console.log(propSymb.length); // 2 |
如果你知道你不必担心
1 | Object.keys(myArray).length |
更新:如果您使用的是underline.js(推荐,它是轻量级的!)那么你就可以
1 2 | _.size({one : 1, two : 2, three : 3}); => 3 |
如果不是,并且您不想因为任何原因而乱搞对象属性,并且已经在使用jquery,则插件同样可以访问:
1 2 3 4 5 6 7 8 | $.assocArraySize = function(obj) { // http://stackoverflow.com/a/6700/11236 var size = 0, key; for (key in obj) { if (obj.hasOwnProperty(key)) size++; } return size; }; |
这是最跨浏览器的解决方案。
这比公认的答案更好,因为它使用本机object.keys(如果存在)。因此,它是所有现代浏览器中速度最快的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | if (!Object.keys) { Object.keys = function (obj) { var arr = [], key; for (key in obj) { if (obj.hasOwnProperty(key)) { arr.push(key); } } return arr; }; } Object.keys(obj).length; |
我不是javascript专家,但看起来您必须循环遍历元素并计算它们,因为对象没有长度方法:
1 2 | var element_count = 0; for (e in myArray) { if (myArray.hasOwnProperty(e)) element_count++; } |
@palmsey:公平地说,javascript文档实际上以这种方式明确地将使用类型为object的变量称为"关联数组"。
此方法在数组中获取对象的所有属性名,因此可以获取该数组的长度,该长度等于对象的键的长度。
1 | Object.getOwnPropertyNames({"hi":"Hi","msg":"Message"}).length; // => 2 |
为了不干扰原型或其他代码,您可以构建和扩展自己的对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | function Hash(){ var length=0; this.add = function(key, val){ if(this[key] == undefined) { length++; } this[key]=val; }; this.length = function(){ return length; }; } myArray = new Hash(); myArray.add("lastname","Simpson"); myArray.add("age", 21); alert(myArray.length()); // will alert 2 |
如果总是使用add方法,那么length属性将是正确的。如果您担心您或其他人忘记使用它,您可以添加其他人发布到length方法的属性计数器。
当然,您可以覆盖这些方法。但是,即使这样做,代码也可能会明显失败,使调试变得容易。;)
最简单的是
1 | Object.keys(myObject).length |
以下是如何并且不要忘记检查属性是否不在原型链上:
1 2 3 4 | var element_count = 0; for(var e in myArray) if(myArray.hasOwnProperty(e)) element_count++; |
这是一个完全不同的解决方案,只能在更现代的浏览器中使用(IE9+、Chrome、Firefox 4+、Opera 11.60+、Safari 5.1+)
参见JSFIDLE
设置关联数组类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /** * @constructor */ AssociativeArray = function () {}; // Make the length property work Object.defineProperty(AssociativeArray.prototype,"length", { get: function () { var count = 0; for (var key in this) { if (this.hasOwnProperty(key)) count++; } return count; } }); |
现在您可以使用以下代码…
1 2 3 4 5 | var a1 = new AssociativeArray(); a1["prop1"] ="test"; a1["prop2"] = 1234; a1["prop3"] ="something else"; alert("Length of array is" + a1.length); |
在某些情况下,最好将大小存储在单独的变量中。特别是,如果你在一个地方用一个元素添加到数组中,并且可以很容易地增加大小。如果你需要经常检查尺寸,它显然会更快地工作。
只需使用这个来获取
1 | Object.keys(myObject).length |
用途:
1 2 3 4 5 6 | var myArray = new Object(); myArray["firstname"] ="Gareth"; myArray["lastname"] ="Simpson"; myArray["age"] = 21; obj = Object.keys(myArray).length; console.log(obj) |
@palmsey: In fairness to the OP, the javascript docs actually explicitly refer to using variables of type Object in this manner as"associative arrays".
< /块引用>
公平地说,@palmsey是非常正确的,它们不是关联数组,它们绝对是对象:)做关联数组的工作。但关于更广泛的观点,根据我发现的这篇相当好的文章,你似乎有权这样做:
javascript"关联数组"被认为是有害的
但根据所有这些,被接受的答案本身不是不好的做法吗?
Specify a prototype size() function for Object
< /块引用>
如果在object.prototype中添加了其他内容,则建议的代码将失败:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 <script type="text/javascript">
Object.prototype.size = function () {
var len = this.length ? --this.length : -1;
for (var k in this)
len++;
return len;
}
Object.prototype.size2 = function () {
var len = this.length ? --this.length : -1;
for (var k in this)
len++;
return len;
}
var myArray = new Object();
myArray["firstname"] ="Gareth";
myArray["lastname"] ="Simpson";
myArray["age"] = 21;
alert("age is" + myArray["age"]);
alert("length is" + myArray.size());我认为答案不应该是可接受的,因为如果在同一执行上下文中运行任何其他代码,那么它就不可能工作。要以一种健壮的方式完成这项工作,您当然需要在myarray中定义size方法,并在迭代成员时检查成员的类型。
如果我们有大麻
hash = {"a" :"b","c":"d"};
我们可以使用键的长度(即哈希的长度)来获取长度:
keys(hash).length
像这样的东西怎么样--
1
2
3
4
5 function keyValuePairs() {
this.length = 0;
function add(key, value) { this[key] = value; this.length++; }
function remove(key) { if (this.hasOwnProperty(key)) { delete this[key]; this.length--; }}
}如果您使用的是AngularJS 1.x,那么您可以通过创建一个过滤器并使用其他示例(如以下)中的代码来执行AngularJS方法:
1
2
3
4
5
6
7
8
9
10 // Count the elements in an object
app.filter('lengthOfObject', function() {
return function( obj ) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
}
})用法
在控制器中:
1 $scope.filterResult = $filter('lengthOfObject')($scope.object)或者在你看来:
1 </any>如果需要显示其大小的关联数据结构,最好使用映射而不是对象。
1
2
3
4
5 var myMap = new Map();
myMap.set("firstname","Gareth");
myMap.set("lastname","Simpson");
myMap.set("age", 21);
myMap.size; // 3上面的一些变化是:
1
2
3
4
5
6
7 var objLength = function(obj){
var key,len=0;
for(key in obj){
len += Number( obj.hasOwnProperty(key) );
}
return len;
};这是一种更优雅的方法来集成hasownprop。
1
2
3
4
5
6
7 myObj = {"key1" :"Hello","key2" :"Goodbye"};
var size = Object.keys(myObj).length;
console.log(size);
<p id="myObj">The number of keys in myObj are: document.write(size)
</p>这对我很有用:
1 var size = Object.keys(myObj).length;如果您不关心支持Internet Explorer 8或更低版本,可以通过应用以下两个步骤轻松获得对象中的属性数:
运行 Object.keys() 以获取一个数组,该数组只包含那些可枚举的属性的名称;如果您还希望包含那些不可枚举的属性的名称,则运行Object.getOwnPropertyNames() 。获取该数组的 .length 属性。如果需要多次执行此操作,可以将此逻辑包装在函数中:
1
2
3
4
5 function size(obj, enumerablesOnly) {
return enumerablesOnly === false ?
Object.getOwnPropertyNames(obj).length :
Object.keys(obj).length;
}如何使用此特定功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 var myObj = Object.create({}, {
getFoo: {},
setFoo: {}
});
myObj.Foo = 12;
var myArr = [1,2,5,4,8,15];
console.log(size(myObj)); // Output : 1
console.log(size(myObj, true)); // Output : 1
console.log(size(myObj, false)); // Output : 3
console.log(size(myArr)); // Output : 6
console.log(size(myArr, true)); // Output : 6
console.log(size(myArr, false)); // Output : 7另请参见此小提琴的演示。
1
2
3
4 var myObject = new Object();
myObject["firstname"] ="Gareth";
myObject["lastname"] ="Simpson";
myObject["age"] = 21;对象.值(myObject).length 对象.条目(myObject).length 对象.键(myObject).length 这是詹姆斯·科根答案的另一个版本。不要传递参数,只需将对象类原型化并使代码更清晰。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 Object.prototype.size = function () {
var size = 0,
key;
for (key in this) {
if (this.hasOwnProperty(key)) size++;
}
return size;
};
var x = {
one: 1,
two: 2,
three: 3
};
x.size() === 3;jfiddle示例:http://jsfiddle.net/qar4j/1/
您可以简单地在任何对象上使用
Object.keys(obj).length 来获取其长度。object.keys返回一个包含所有对象键(属性)的数组,使用相应数组的长度可以方便地找到该对象的长度。甚至可以为此编写函数。让我们创造性地为它编写一个方法(以及更方便的getter属性):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 function objLength(obj)
{
return Object.keys(obj).length;
}
console.log(objLength({a:1, b:"summit", c:"nonsense"}));
// Works perfectly fine
var obj = new Object();
obj['fish'] = 30;
obj['nullified content'] = null;
console.log(objLength(obj));
// It also works your way, which is creating it using the Object constructor
Object.prototype.getLength = function() {
return Object.keys(this).length;
}
console.log(obj.getLength());
// You can also write it as a method, which is more efficient as done so above
Object.defineProperty(Object.prototype,"length", {get:function(){
return Object.keys(this).length;
}});
console.log(obj.length);
// probably the most effictive approach is done so and demonstrated above which sets a getter property called"length" for objects which returns the equivalent value of getLength(this) or this.getLength()最简单的方法是这样
1 Object.keys(myObject).length其中myObject是所需长度的对象
您可以始终执行
Object.getOwnPropertyNames(myObject).length ,以获得与正常数组[].length 相同的结果。下面是一个版本的詹姆斯·科格兰(JamesCoglan)在《咖啡描述》(Coffeescript)中对那些放弃了纯javascript的人的回答:)
1
2
3
4 Object.size = (obj) ->
size = 0
size++ for own key of obj
size
财产
1
2
3
4
5
6
7
8
9 Object.defineProperty(Object.prototype, 'length', {
get: function () {
var size = 0, key;
for (key in this)
if (this.hasOwnProperty(key))
size++;
return size;
}
});使用
1
2
3
4 var o = {a: 1, b: 2, c: 3};
alert(o.length); // <-- 3
o['foo'] = 123;
alert(o.length); // <-- 4我们可以通过以下方法找到物体的长度:
1 Object.values(myObject).length虽然比游戏晚了一点,但实现这一点的一个好方法(仅限IE9+)是在length属性上定义一个魔力getter:
1
2
3
4
5 Object.defineProperty(Object.prototype,"length", {
get: function () {
return Object.keys(this).length;
}
});你可以这样使用它:
1
2 var myObj = { 'key': 'value' };
myObj.length;会给
1 。和大多数javascript问题一样,有很多解决方案。您可以扩展对象,使其更好或更差地工作,就像许多其他语言的字典(+一流公民)。这没什么错,但另一个选择是构造一个满足您特定需求的新对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14 function uberject(obj){
this._count = 0;
for(var param in obj){
this[param] = obj[param];
this._count++;
}
}
uberject.prototype.getLength = function(){
return this._count;
};
var foo = new uberject({bar:123,baz:456});
alert(foo.getLength());简单解决方案:
1
2
3
4
5
6
7
8
9
10
11 var myObject = {}; // ... your object goes here.
var length = 0;
for (var property in myObject) {
if (myObject.hasOwnProperty(property)){
length += 1;
}
};
console.log(length); // logs 0 in my example.对象继承时,
Object.keys 不返回权利结果。要正确计算对象属性,包括继承的属性,请使用for-in ,例如通过以下函数(相关问题)
1 var objLength = (o,i=0) => { for(p in o) i++; return i }
1
2
3
4
5
6
7
8
9
10
11
12
13 var myObject = new Object();
myObject["firstname"] ="Gareth";
myObject["lastname"] ="Simpson";
myObject["age"] = 21;
var child = Object.create(myObject);
child["sex"] ="male";
var objLength = (o,i=0) => { for(p in o) i++; return i }
console.log("Object.keys(myObject):", Object.keys(myObject).length,"(OK)");
console.log("Object.keys(child) :", Object.keys(child).length,"(wrong)");
console.log("objLength(child) :", objLength(child),"(OK)");该解决方案适用于许多情况和跨浏览器:
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 var getTotal = function(collection) {
var length = collection['length'];
var isArrayObject = typeof length == 'number' && length >= 0 && length <= Math.pow(2,53) - 1; // Number.MAX_SAFE_INTEGER
if(isArrayObject) {
return collection['length'];
}
i= 0;
for(var key in collection) {
if (collection.hasOwnProperty(key)) {
i++;
}
}
return i;
};数据实例:
1
2
3
4
5
6
7
8
9
10
11
12
13 // case 1
var a = new Object();
a["firstname"] ="Gareth";
a["lastname"] ="Simpson";
a["age"] = 21;
//case 2
var b = [1,2,3];
// case 3
var c = {};
c[0] = 1;
c.two = 2;用法
1
2
3 getLength(a); // 3
getLength(b); // 3
getLength(c); // 2在我看来,最好的答案是,
if (obj.hasOwnProperty(key)) 控制是多余的。它总是返回true 。
1
2
3
4
5
6
7 Object.size = function(obj) {
var size = 0, key;
for (key in obj) {
size++;
}
return size;
};
1
2
3
4
5
6
7
8 var myObject = new Object();
myObject["firstname"] ="Gareth";
myObject["lastname"] ="Simpson";
myObject["age"] = 21;
var size = JSON.stringify(myObject).length;
document.write(size);
1 JSON.stringify(myObject)