JavaScript 对象的长度

Length of a JavaScript object

提问人:Gareth Simpson 提问时间:8/8/2008 最后编辑:Ran TurnerGareth Simpson 更新时间:8/12/2023 访问量:2877009

问:

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

const myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
对象 JavaScript 对象

评论

1赞 cloudfeet 7/24/2013
@neitony - 这有点正确,但是很多人已经习惯了PHP的“关联数组”,以至于他们可能会认为它的意思是“有序的关联映射”,而JS对象实际上是无的。
4赞 Andrew Koster 5/11/2019
在上面的示例中,myObject.length 是未定义的,至少在浏览器环境中是这样。这就是为什么它无效,@AdrianM
3赞 Sebastian Simon 3/15/2021
{, , } 的变体现在在 16 个答案中总共被提及 38 次,在 7 个删除的答案中又被提及 11 次。我认为现在已经足够了。Object.keysvaluesentries(obj).length

答:

44赞 jj33 8/8/2008 #1

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

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

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

评论

9赞 Lajos Mészáros 10/8/2013
将不起作用,因为它也会计算通过原型添加的方法。
25赞 doekman 8/9/2008 #2

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

var element_count = 0;
for(var e in myArray)
    if(myArray.hasOwnProperty(e))
        element_count++;
17赞 Polsonby 8/9/2008 #3

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

公平地说,@palmsey他是完全正确的。它们不是关联数组;它们绝对是对象:) - 执行关联数组的工作。但就更广泛的观点而言,根据我发现的这篇相当不错的文章,您似乎绝对有权这样做:

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

但根据这一切,公认的答案本身就是不好的做法吗?

为 Object 指定原型 size() 函数

如果向 Object .prototype 添加了任何其他内容,则建议的代码将失败:

<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 方法,并在遍历成员时检查成员的类型。

3359赞 James Coglan 8/9/2008 #4

更新的答案

以下是截至 2016 年的更新以及 ES5 及更高版本的广泛部署。对于 IE9+ 和所有其他支持 ES5+ 的现代浏览器,你可以使用 Object.keys(),所以上面的代码就变成了:

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

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

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

符号类型已添加到语言中,以便为对象属性创建唯一标识符。符号类型的主要优点是防止覆盖。

Object.keys或不适用于符号属性。要返回它们,您需要使用 .Object.getOwnPropertyNamesObject.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 object
const myObj = {}
var size = Object.size(myObj);

JavaScript 中有一种约定,你不会向 Object.prototype 添加内容,因为它会破坏各种库中的枚举。不过,向 Object 添加方法通常是安全的。


评论

68赞 vsync 6/14/2011
@Tres - 如果有人来覆盖“size”属性,而不知道你已经在代码中的某个地方声明了它,你的代码可能会被破坏,所以总是值得检查它是否已经定义
19赞 Tres 6/24/2011
@vsync 你说得很对。人们应该始终实施必要的健全性检查:)
160赞 Muhammad Umer 2/25/2015
为什么每个人都忽略了这一点:Object.keys(obj).length
37赞 Chris Hayes 5/9/2015
@MuhammadUmer 可能是因为在写这个答案时,这种方法甚至不存在。即使在今天,使用它也可能需要旧浏览器的 polyfill。
25赞 Lukas Liesis 1/19/2016
@stonyau IE8、IE9、IE10 都是死浏览器,没有得到Microsoft的支持。IE8,IE9,IE10用户收到来自Microsoft的通知,他们使用旧的,不受支持的浏览器,并且应该期望这些东西对他们不起作用。support.microsoft.com/en-us/kb/3123303
2029赞 aeosynth 4/3/2011 #5

如果您知道不必担心检查,则可以通过以下方式使用 Object.keys() 方法:hasOwnProperty

Object.keys(myArray).length

评论

25赞 vsync 6/6/2011
为什么不呢?据我所知,这是一个标准:developer.mozilla.org/en/JavaScript/Reference/Global_Objects/......
109赞 aeosynth 6/7/2011
这不是一个普遍实现的方法,但您可以使用此表检查哪个浏览器支持它。
27赞 mdup 8/13/2012
是时候切换到 Firefox 了 = 不幸的是,您切换并不意味着您网站的用户会......
87赞 John Dvorak 12/13/2012
@ripper234 不支持 IE = 填充时间
24赞 albanx 3/21/2014
@ripper234谁在乎IE,谁就不应该在乎IE的不标准,只在乎标准。用户想使用IE浏览器,那么他们就不会浏览我的网站,我不在乎了。开发人员不应 polyfill 不是由“开发人员”制定的标准
31赞 DanMan 6/11/2011 #6

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

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 方法中。

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

评论

0赞 Emeka Mbah 6/2/2016
我认为这是最好的解决方案,因为它不需要使用“for”循环,如果数组很大,这可能会很昂贵
18赞 Jānis Elmeris 7/29/2011 #7

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

13赞 Jerry 8/24/2011 #8

像这样的事情呢?

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--; }}
}
10赞 wade harrell 11/19/2011 #9

上述一些内容的变体是:

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

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

313赞 ripper234 7/5/2012 #10

更新:如果你使用的是下划线.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;
};

评论

8赞 tokyovariable 8/2/2013
_.size()是我的 Meteor 项目的完美解决方案,它具有下划线的 .js 支持。
4赞 jbolanos 11/21/2013
我使用下划线,这篇文章只是提醒我,我在这个项目中使用它还不够。如果处理对象,则应具有下划线 .js 可用。
3赞 Rayjax 4/11/2014
下划线>(全部 -['lo-dash'])
0赞 MinhajulAnwar 10/30/2015
下划线js,应该在js下的东西:)
1赞 ripper234 2/13/2017
@Babydead区分对象的真实属性与继承属性。developer.mozilla.org/en/docs/Web/JavaScript/Reference/......
7赞 Sherzod 6/27/2013 #11

这是詹姆斯·科根(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/

评论

6赞 Dziad Borowy 10/14/2013
Object.prototype- 坏主意。
0赞 Mohamad 3/5/2014
@tborychowski你能解释一下原因吗?
0赞 Dziad Borowy 3/5/2014
这是一篇文章:bit.ly/1droWrG。我并不是说它不能这样做,只是你需要在这样做之前知道所有的影响。
0赞 Sebastian Simon 5/9/2020
如果您要扩展内置原型或填充属性(即 monkey-patch),请正确执行:为了向前兼容,请先检查该属性是否存在,然后使该属性不可枚举,以便构造对象的自己的键不会受到污染。对于方法,请使用实际方法。我的建议:遵循这些示例,这些示例演示了如何添加一个行为尽可能接近内置方法的方法。
24赞 Ally 8/2/2013 #12

这是一个完全不同的解决方案,仅适用于更现代的浏览器(Internet Explorer 9+、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);

评论

0赞 Panos Theof 10/26/2014
我认为这是不安全的。例如,它不能有一个键为 “length” 的元素,语句 a1[“length”] = “Hello world”;无法存储条目。还有语句 a1[“hasOwnProperty”] = “some prop”;完全破坏功能
3赞 Ally 10/27/2014
@PanosTheof 如果您使用该属性,我认为您不希望它存储值,任何使用它的代码都必须确保它不会尝试存储,但我想如果它也是一个标准数组,那将是相同的。覆盖任何对象很可能会产生不希望的结果。lengthlengthhasOwnProperty
71赞 Joon 9/2/2013 #13

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

这比公认的答案要好,因为它使用本机 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;

评论

8赞 John Slegers 3/7/2016
Object.keys()返回一个数组,该数组仅包含可枚举的那些属性的名称。如果您想要一个具有 ALL 属性的数组,则应改用。查看 developer.mozilla.org/en/docs/Web/JavaScript/Reference/...Object.getOwnPropertyNames()
15赞 abo-elleef 2/9/2014 #14

如果我们有哈希值

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

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

keys(hash).length

评论

2赞 chim 9/3/2015
这是一个很好的答案,但是我找不到此键功能的任何文档。所以我对跨浏览器支持没有信心。
2赞 chim 9/3/2015
不幸的是,这并不像我最初想象的那么好!事实证明,按键功能仅在 chrome 和 firefox 网络控制台中可用。如果将此代码放入脚本中,则它将失败,并显示 Uncaught ReferenceError: keys is not defined
1赞 Peter Mortensen 9/18/2016
这与 aeosynth 的答案有何不同?
38赞 venkat7668 7/1/2014 #15

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

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

评论

1赞 Muhammad Umer 2/27/2015
@PatrickRoberts键方法不从原型链返回属性。那么为什么这里需要hasOwnProperty。此外,getOwnProperty 将返回隐藏属性,因为长度在数组中等。
12赞 pcnate 9/16/2015 #16

如果您使用的是 AngularJS 1.x,您可以通过创建过滤器并使用任何其他示例中的代码来执行 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>

评论

4赞 hodgef 12/5/2015
OP 没有要求 AngularJS 版本。这不是对这个问题的有效答案。
6赞 Pian0_M4n 1/12/2016 #17

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

评论

1赞 John Slegers 3/7/2016
Object.keys()返回一个数组,该数组仅包含可枚举的那些属性的名称。如果您想要一个具有 ALL 属性的数组,则应改用。查看 developer.mozilla.org/en/docs/Web/JavaScript/Reference/...Object.getOwnPropertyNames()
3赞 Peter Mortensen 9/18/2016
这与 aeosynth 的答案有何不同?
10赞 John Slegers 3/7/2016 #18

如果您不关心是否支持 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;
}

如何使用此特定功能:

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

另请参阅此 Fiddle 的演示。

20赞 Oriol 5/19/2016 #19

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

const myMap = new Map();

myMap.set("firstname", "Gareth");
myMap.set("lastname", "Simpson");
myMap.set("age", 21);

console.log(myMap.size); // 3

19赞 Mahendra Kulkarni 5/31/2016 #20

用:

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

5赞 Mystical 9/17/2016 #21

您可以简单地在任何对象上使用来获取其长度。Object.keys 返回一个包含所有对象(属性)的数组,该数组可用于使用相应数组的长度查找该对象的长度。您甚至可以为此编写一个函数。让我们发挥创意,为它编写一个方法(以及一个更方便的 getter 属性):Object.keys(obj).length

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

评论

4赞 Peter Mortensen 9/18/2016
这与 aeosynth 的答案有何不同?
0赞 Mystical 9/18/2016
这是因为它展示了如何将其作为函数和全局对象方法(更面向对象并使用某种形式的封装);然而,Aeosynth 的答案并非如此。
0赞 Sebastian Simon 5/9/2020
如果您要扩展内置原型或填充属性(即 monkey-patch),请正确执行:为了向前兼容,请先检查该属性是否存在,然后使该属性不可枚举,以便构造对象的自己的键不会受到污染。对于方法,请使用实际方法。我的建议:遵循这些示例,这些示例演示了如何添加一个行为尽可能接近内置方法的方法。
0赞 Sebastian Simon 5/9/2020
另外,编写方法如何“更有效”?
29赞 solanki... 5/22/2017 #22

我们可以通过以下方法找到 Object 的长度:

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

评论

0赞 JSG 6/7/2021
从理论上讲,如果您有长值,他的值会比“键”方法慢,因为它直接访问值然后计算它们。
4赞 MacroMan 7/4/2017 #23

实现此目的的一个好方法(仅限 Internet Explorer 9+)是在 length 属性上定义一个魔术吸气器:

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

你可以像这样使用它:

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

它会给.1

评论

2赞 MacroMan 8/13/2019
撇开反对原型修改的论点不谈,我个人从来没有遇到过由它引起的错误,对我来说,这是 JavaScript 的强项之一。
48赞 saurabhgoyal795 1/18/2018 #24

只需使用它即可获得:length

Object.keys(myObject).length

评论

13赞 Patata 2/13/2018
请解释您的答案与 stackoverflow.com/a/6700/8632727 有何不同
1赞 Barry Michael Doyle 4/4/2018
很好,最好根据变量的实际情况来命名变量。使您的代码对其他开发人员更具可读性。
6赞 Yunnosch 5/25/2018
在 “myArray” -> “myObject” 编辑之前,这与第二高的赞成答案相同。
5赞 Alberto Perez 8/27/2019
与过去的回复相同。
0赞 Zsolt Meszaros 8/26/2023
与链接的答案相同,但没有任何解释。
14赞 tdjprog 4/6/2018 #25
var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
  1. Object.values(myObject).length
  2. Object.entries(myObject).length
  3. Object.keys(myObject).length

评论

1赞 Siluveru Kiran Kumar 6/21/2019
以上 3 种中哪一种更快。
1赞 tdjprog 7/2/2019
Object.values(myObject).length
1赞 Siluveru Kiran Kumar 7/2/2019
我们怎么能说它 Object.values(myObject).length 更快 有没有例子 谢谢,@tdjprog
1赞 tdjprog 7/3/2019
只需在控制台中尝试以下操作:var myObject = {}; for (let i=0; i<10000000; i++) myObject[i] = i;
1赞 Siluveru Kiran Kumar 7/3/2019
为什么 Object.values(myObject).length 更快,而 Object.entries(myObject).length 即使在一段时间后也不给出输出,这是什么原因?谢谢@tdjprog
18赞 Mithu A Quayium 5/30/2018 #26

最简单的方法是这样的:

Object.keys(myobject).length

其中 myobject 是您想要的长度的对象。

评论

4赞 Pang 11/15/2018
这似乎只是对现有答案的重复。
0赞 Mystical 1/21/2019
@Pang同意的,它没有像其他答案那样提供任何进一步的背景。
19赞 PythonProgrammi 6/6/2018 #27

<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;
20赞 shaheb 9/8/2019 #28

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

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

console.log(Object.keys(myObject).length); //3

11赞 Soura Ghosh 1/11/2020 #29
const myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;

console.log(Object.keys(myObject).length)

// o/p 3

评论

0赞 Peter Mortensen 7/11/2020
“o/p 3” 是什么意思?
0赞 Peter Mortensen 7/11/2020
对这个答案的解释是有序的。
2赞 Peter Mortensen 7/11/2020
另外,它与之前的答案有何不同,例如 shaheb 的答案
0赞 Sebastian Simon 3/15/2021
@PeterMortensen“o/p”可能意味着“输出”。
0赞 Soura Ghosh 3/16/2021
O/P 表示输出
17赞 Ran Turner 4/22/2022 #30

使用该方法获取长度是实现它的一种方法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)); // 3
console.log(objectLength(car)); // 2