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+的现代浏览器,您可以使用Object.keys(),因此上面的代码只是:
1
| var size = Object.keys(myObj).length; |
这不需要修改任何现有的原型,因为Object.keys()现在已经内置了。 编辑:对象可以具有不能通过object.key方法返回的符号属性。因此,如果不提及它们,答案将是不完整的。 符号类型已添加到语言中,以创建对象属性的唯一标识符。符号类型的主要好处是防止覆盖。 Object.keys或Object.getOwnPropertyNames不适用于符号属性。要退货,您需要使用Object.getOwnPropertySymbols。
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 |
如果你知道你不必担心hasOwnProperty支票,你可以很简单地做到:
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); |
在某些情况下,最好将大小存储在单独的变量中。特别是,如果你在一个地方用一个元素添加到数组中,并且可以很容易地增加大小。如果你需要经常检查尺寸,它显然会更快地工作。
只需使用这个来获取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 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) |
|