JavaScript对象的长度

如果我有一个JavaScript对象,说

var myObject = new Object(); myObject["firstname"] = "Gareth"; myObject["lastname"] = "Simpson"; myObject["age"] = 21; 

是否有一个内置或接受的最佳实践方式来获得这个对象的长度?

最强大的答案(即捕捉你想要做的事情的意图,同时造成最less的错误)将是:

 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中 ,因为它可能会破坏各种库中的枚举。 不过,向Object添加方法通常是安全的。


这里是2016年的更新以及ES5及其以后的广泛部署 。 对于IE9 +和所有其他现代ES5 +浏览器,您可以使用Object.keys()以便上面的代码变成:

 var size = Object.keys(myObj).length; 

由于现在内置了Object.keys()所以不需要修改任何现有的原型。

如果你知道你不必担心hasOwnProperty检查,你可以很简单地做到这一点:

 Object.keys(myArray).length 

更新 :如果你使用Underscore.js (推荐,它是轻量级!),那么你可以做

 _.size({one : 1, two : 2, three : 3}); => 3 

如果不是 ,并且不想因为任何原因而乱搞Object属性,并且已经在使用jQuery,则同样可以访问一个插件:

 $.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(obj).length 

它不一定是困难的,绝对不需要另外的function来完成。

这是最多的跨浏览器解决scheme。

这比接受的答案要好,因为如果存在的话,它使用本地的Object.keys。 因此,它是所有现代浏览器中最快的。

 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专家,但它看起来像你将不得不遍历的元素和数量,因为对象没有一个长度的方法:

 var element_count = 0; for (e in myArray) { if (myArray.hasOwnProperty(e)) element_count++; } 

@palmsey:为了公平性,JavaScript文档实际上明确提到了以这种方式使用Objecttypes的variables作为“关联数组”。

这个方法获取数组中所有对象的属性名称,所以你可以得到这个数组的长度等于你的对象的键的长度。

 Object.getOwnPropertyNames({"hi":"Hi","msg":"Message"}).length; // => 2 

为了不弄乱原型或其他代码,你可以构build和扩展你自己的对象:

 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属性将是正确的。 如果您担心自己或其他人忘记使用它,则可以将其他人发布的属性计数器添加到长度方法中。

当然,你总是可以覆盖的方法。 但是,即使你这样做,你的代码也可能会失败,使debugging变得容易。 ;)

以下是如何以及不要忘记检查该属性是否在原型链上:

 var element_count = 0; for(var e in myArray) if(myArray.hasOwnProperty(e)) element_count++; 

这是一个完全不同的解决scheme,只能在更现代的浏览器(IE9 +,Chrome,Firefox 4 +,Opera 11.60 +,Safari 5.1+)

见jsFiddle

设置您的关联数组类

 /** * @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; } }); 

现在你可以使用这个代码如下…

 var a1 = new AssociativeArray(); a1["prop1"] = "test"; a1["prop2"] = 1234; a1["prop3"] = "something else"; alert("Length of array is " + a1.length); 

在某些情况下,最好将大小存储在单独的variables中。 特别是,如果你在一个地方添加一个元素,并且可以轻松地增加大小。 如果您需要经常检查大小,它显然会工作得更快。

使用:

 var myArray = new Object(); myArray["firstname"] = "Gareth"; myArray["lastname"] = "Simpson"; myArray["age"] = 21; obj = Object.keys(myArray).length; console.log(obj) 

@palmsey:公平地说,JavaScript文档实际上明确提到使用Objecttypes的variables作为“关联数组”。

公平地说@palmsey他是非常正确的,他们不是联合数组,他们绝对是对象:) – 做一个关联数组的工作。 但是,从更广泛的angular度来看,你肯定有权利根据这篇相当精美的文章,我发现:

JavaScript“关联数组”被认为是有害的

但根据这一切,不是被接受的答案本身不好的做法?

指定Object的原型大小()函数

如果其他东西已经添加到Object .prototype,那么build议的代码将失败:

 <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()); </script> 

我不认为这个答案应该是被接受的,因为如果你有其他的代码在同一个执行上下文中运行的话,它不能被信任。 为了以一种可靠的方式确实做到这一点,您需要在myArray中定义size方法,并在遍历它们时检查成员的types。

那么像这样的东西 –

 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--; }} } 

如果我们有散列

hash = {“a”:“b”,“c”:“d”};

我们可以使用哈希长度的密钥长度来得到长度:

键(散列)。长度

如果您正在使用AngularJS 1.x,则可以通过创build一个filter并使用其他任何示例(如下所示)中的代码来执行AngularJS方法:

 // 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; } }) 

用法

在你的控制器中:

 $scope.filterResult = $filter('lengthOfObject')($scope.object) 

或者在你看来:

 <any ng-expression="object | lengthOfObject"></any> 

以上的一些变化是:

 var objLength = function(obj){ var key,len=0; for(key in obj){ len += Number( obj.hasOwnProperty(key) ); } return len; }; 

整合hasOwnProp是一种更优雅的方式。

如果您需要公开其大小的关联数据结构,则最好使用地图而不是对象。

 var myMap = new Map(); myMap.set("firstname", "Gareth"); myMap.set("lastname", "Simpson"); myMap.set("age", 21); myMap.size; // 3 

如果您不关心支持Internet Explorer 8或更低版本,则可以通过应用以下两个步骤轻松获取对象中的属性数量:

  1. 如果要包含不可枚举的属性的名称,请运行Object.keys()以获取仅包含可枚举的属性或Object.getOwnPropertyNames()的名称的数组。
  2. 获取该数组的.length属性。

如果你不止一次需要这样做,你可以把这个逻辑包装在一个函数中:

 function size(obj, enumerablesOnly) { return enumerablesOnly === false ? Object.getOwnPropertyNames(obj).length : Object.keys(obj).length; } 

如何使用这个特殊的function:

 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 

另请参阅此小提琴演示。

这是James Cogan的答案的另一个版本。 而不是传递一个参数,只是原型的对象类,并使代码更清洁。

 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; 

jsfiddle例子: http : //jsfiddle.net/qar4j/1/

你可以在任何对象上简单地使用Object.keys(obj).length来获得它的长度。 Object.keys返回一个包含所有对象关键字 (属性)的数组,这些对象关键字可以派上用场,使用相应数组的长度来查找该对象的长度。 你甚至可以为此写一个函数 。 让我们变得富有创造性,并为它写一个方法 (以及一个更方便的getter属性):

 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() 

你总是可以做Object.getOwnPropertyNames(myObject).length来得到和[].length给普通数组一样的结果。

下面是James Coglan在CoffeeScript中为那些已经放弃JavaScript的人的回答的一个版本:)

 Object.size = (obj) -> size = 0 size++ for own key of obj size 

属性

 Object.defineProperty(Object.prototype, 'length', { get: function () { var size = 0, key; for (key in this) if (this.hasOwnProperty(key)) size++; return size; } }); 

使用

 var o = {a: 1, b: 2, c: 3}; alert(o.length); // <-- 3 o['foo'] = 123; alert(o.length); // <-- 4 

像大多数JavaScript问题一样,有很多解决scheme。 你可以扩展对象,使其更好或更差的作品像其他许多语言词典(+一等公民)。 没有错,但另一个select是构build一个新的对象,以满足您的具体需求。

 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()); 

我们可以用下面的方法findObject的长度:

 Object.values(myObject).length 

有点迟到的游戏,但一个很好的方法来实现这一点(只有IE9 +)是定义一个魔术getter的长度属性:

 Object.defineProperty(Object.prototype, "length", { get: function () { return Object.keys(this).length; } }); 

你可以像这样使用它:

 var myObj = { 'key': 'value' }; myObj.length; 

会给1

简单的scheme:

  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. 

该解决scheme适用于多种情况和跨浏览器:

 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; }; 

数据示例:

 // 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; 

用法

 getLength(a); // 3 getLength(b); // 3 getLength(c); // 2 

如果你正在使用jQuery,只需要使用对象的.length方法。

$(object).length会给你传递的对象的长度。

更新 :这将始终返回1的情况下,但与jQuery元素很好地工作。