JavaScript对象的长度

我有一个JavaScript对象。是否有内置或公认的最佳实践方法来获取此对象的长度?

const myObject = new Object();myObject["firstname"] = "Gareth";myObject["lastname"] = "Simpson";myObject["age"] = 21;
2700054 次浏览

我不是JavaScript专家,但看起来你必须循环遍历元素并计算它们,因为Object没有长度方法:

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

@palmsey:为了公平起见,JavaScript留档实际上明确地将以这种方式使用Object类型的变量称为“关联数组”。

以下是方法,不要忘记检查属性是否不在原型链上:

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

@palmsey:为了公平起见,JavaScript留档实际上明确地将以这种方式使用Object类型的变量称为“关联数组”。

公平地说,@palmsey他是非常正确的。它们不是关联数组;它们绝对是对象:)-做关联数组的工作。但是关于更广泛的一点,根据我找到的这篇相当不错的文章,你似乎绝对有权这样做:

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

但根据所有这些,公认的答案本身就是不好的做法?

为Object指定原型size()函数

如果有其他东西被添加到Object.原型中,那么建议的代码将失败:

<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方法,并在迭代成员时检查它们的类型。

更新答案

以下是截至2016年的更新和ES5的广泛部署及以后。对于IE9+和所有其他支持ES5+的现代浏览器,您可以使用#0,因此上面的代码变成:

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

这不需要修改任何现有的原型,因为Object.keys()现在是内置的。

编辑:对象可以具有不能通过Object.key方法返回的符号属性。因此,如果不提及它们,答案将是不完整的。

符号类型被添加到语言中以创建对象属性的唯一标识符。符号类型的主要好处是防止覆盖。

Object.keysObject.getOwnPropertyNames不适用于符号属性。要返回它们,您需要使用Object.getOwnPropertySymbols

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

老答案

最可靠的答案(即在引起最少错误的同时捕获您尝试做的事情的意图)是:

Object.size = function(obj) {var size = 0,key;for (key in obj) {if (obj.hasOwnProperty(key)) size++;}return size;};
// Get the size of an objectconst myObj = {}var size = Object.size(myObj);

JavaScript中有一种约定不要给Object.prototype添加东西,因为它可以破坏各种库中的枚举。不过,向Object添加方法通常是安全的。


如果你知道你不必担心hasOwnProperty检查,你可以这样使用Object.keys()方法:

Object.keys(myArray).length

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

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

当然,你总是可以覆盖这些方法。但即使你这样做了,你的代码也可能会明显失败,从而很容易调试。;)

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

像这样的东西怎么样

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

上述一些的变体是:

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

这是一种更优雅的集成hasOwnProp的方式。

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

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

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

$.assocArraySize = function(obj) {// http://stackoverflow.com/a/6700/11236var size = 0, key;for (key in obj) {if (obj.hasOwnProperty(key)) size++;}return size;};

以下是James Coglan在CoffeeScript中的回答版本,适用于那些放弃直接JavaScript的人:)

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

这是James Cogan答案的不同版本。而不是传递参数,只需原型化Object类并使代码更清晰。

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/

这是一个完全不同的解决方案,只适用于更现代的浏览器(Internet Explorer 9+,Chrome,Firefox 4+,Opera 11.60+和Safari5.1+)

这个jsFiddle

设置关联数组类

/*** @constructor*/AssociativeArray = function () {};
// Make the length property workObject.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);

这是最跨浏览器的解决方案。

这比接受的答案更好,因为它使用本地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;

如果我们有散列

hash={"a":"b","c":"d"};

我们可以使用键的长度来获取长度,这是哈希的长度:

键(哈希).长度

像大多数JavaScript问题一样,有许多解决方案。您可以扩展Object,无论好坏,它都像许多其他语言的字典(+一等公民)一样工作。这没有错,但另一种选择是构建一个满足您特定需求的新对象。

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

此方法获取数组中所有对象的属性名称,因此您可以获取该数组的长度,该长度等于对象的键的长度。

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

物业

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); // <-- 3o['foo'] = 123;alert(o.length); // <-- 4

简单的解决方案:

  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.

如果您使用的是AngularJS 1. x,您可以通过创建过滤器并使用来自以下任何其他示例的代码来以AngularJS的方式做事:

// Count the elements in an objectapp.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>

您始终可以执行Object.getOwnPropertyNames(myObject).length以获得与[].length对普通数组给出的结果相同的结果。

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

  1. 如果您还想包含不可枚举的属性的名称,请运行#0以获取仅包含可枚举#1属性名称的数组。
  2. 获取该数组的#0属性。

如果你需要多次执行此操作,你可以将此逻辑包装在一个函数中:

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

如何使用此特定功能:

var myObj = Object.create({}, {getFoo: {},setFoo: {}});myObj.Foo = 12;
var myArr = [1,2,5,4,8,15];
console.log(size(myObj));        // Output : 1console.log(size(myObj, true));  // Output : 1console.log(size(myObj, false)); // Output : 3console.log(size(myArr));        // Output : 6console.log(size(myArr, true));  // Output : 6console.log(size(myArr, false)); // Output : 7

另见这个小提琴演示。

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

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

用途:

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

该解决方案适用于许多情况和跨浏览器:

代码

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 1var a = new Object();a["firstname"] = "Gareth";a["lastname"] = "Simpson";a["age"] = 21;
//case 2var b = [1,2,3];
// case 3var c = {};c[0] = 1;c.two = 2;

用法

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

您可以简单地在任何对象上使用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 finevar 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 constructorObject.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的长度:

const myObject = {};console.log(Object.values(myObject).length);

实现这一点的一个好方法(仅限Internet Explorer 9+)是在长度属性上定义一个神奇的getter:

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

你可以像这样使用它:

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

它会给1

简单地使用它来获取length

Object.keys(myObject).length
var myObject = new Object();myObject["firstname"] = "Gareth";myObject["lastname"] = "Simpson";myObject["age"] = 21;
  1. Object.values(myObject)
  2. Object.entries(myObject)
  3. Object.keys(myObject)

var myObject = new Object();myObject["firstname"] = "Gareth";myObject["lastname"] = "Simpson";myObject["age"] = 21;
var size = JSON.stringify(myObject).length;
document.write(size);

JSON.stringify(myObject)

最简单的方法是这样的:

Object.keys(myobject).length

其中myObject是你想要的长度的对象。

<script>myObj = {"key1" : "Hello", "key2" : "Goodbye"};var size = Object.keys(myObj).length;console.log(size);</script>
<p id="myObj">The number of <b>keys</b> in <b>myObj</b> are: <script>document.write(size)</script></p>

这对我有用:

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

在对象继承的情况下,Object.keys确实没有返回正确的结果。要正确计算对象属性,包括继承的属性,请使用for-in。例如,通过以下函数(与问题相关):

var objLength = (o,i=0) => { for(p in o) i++; return i }

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

我也有类似的需求来计算通过WebSocket接收的对象使用的带宽。简单地找到Stringify对象的长度对我来说就足够了。

websocket.on('message', data => {dataPerSecond += JSON.stringify(data).length;}

使用Object.keys(myObject).length获取对象/数组的长度

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

const myObject = new Object();myObject["firstname"] = "Gareth";myObject["lastname"] = "Simpson";myObject["age"] = 21;
console.log(Object.keys(myObject).length)
// o/p 3

使用ECMAScript 6内置的Reflect对象,您可以轻松计算对象的属性:

Reflect.ownKeys(targetObject).length

它将为您提供目标对象自身属性的长度(重要)。

Reflect.ownKeys(target)

返回目标对象自身(非继承)属性的数组钥匙。

现在,这是什么意思?为了解释这个,让我们看看这个例子。

function Person(name, age){this.name = name;this.age = age;}
Person.prototype.getIntro= function() {return `${this.name} is ${this.age} years old!!`}
let student = new Person('Anuj', 11);
console.log(Reflect.ownKeys(student).length) // 2console.log(student.getIntro()) // Anuj is 11 years old!!

您可以在这里看到,它只返回了自己的属性,而对象仍在从其父级继承属性。

有关更多信息,请参阅:反映API

简单的一个班轮:

console.log(Object.values({id:"1",age:23,role_number:90}).length);

尝试:Object.values(theObject).length

const myObject = new Object();myObject["firstname"] = "Gareth";myObject["lastname"] = "Simpson";myObject["age"] = 21;console.log(Object.values(myObject).length);

 vendor = {1: "", 2: ""}const keysArray = Object.keys(vendor)const objectLength = keysArray.lengthconsole.log(objectLength)Result 2

在这里您可以给出任何类型的变量数组、对象、字符串

function length2(obj){if (typeof obj==='object' && obj!== null){return Object.keys(obj).length;}//if (Array.isArray){return obj.length;}return obj.length;
}

使用Object.entries方法获取长度是实现它的一种方法

const objectLength = obj => Object.entries(obj).length;
const person = {id: 1,name: 'John',age: 30}  
const car = {type: 2,color: 'red',}
console.log(objectLength(person)); // 3console.log(objectLength(car)); // 2