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或更低版本,则可以通过应用以下两个步骤轻松获取对象中的属性数量:
- 如果要包含不可枚举的属性的名称,请运行
Object.keys()
以获取仅包含可枚举的属性或Object.getOwnPropertyNames()
的名称的数组。 - 获取该数组的
.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元素很好地工作。