JavaScript对象的长度


2382

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

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

14
默认情况下,JavaScript中的对象文字是关联数组,例如object.propertyName.propertyValue与object [propertyName] [propertyValue]相同
neitony 2011年


31
一旦行答案是使用@aeosynth所说的Object.keys(myArray).length。
Ranadheer Reddy 2013年

67
好的,怎么样Object.keys(obj).length
穆罕默德·乌默尔

5
为什么object.length无效?它为我返回正确的结果。
阿德里安M

Answers:


2620

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

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

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


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

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

由于它Object.keys()是内置的,因此无需修改任何现有的原型。

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

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

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

65
@Tres-如果有人不知道您在代码中已经声明了'size'属性而将其破坏,则您的代码可能会损坏,因此始终值得检查它是否已定义
vsync

19
@vsync您非常正确。人们应该始终进行必要的健全性检查:)
Tres

132
为什么每个人都忽略这一点:Object.keys(obj).length
穆罕默德·乌默尔

33
@MuhammadUmer可能是因为在编写此答案时该方法甚至不存在。即使在今天,使用它也可能需要旧浏览器使用polyfill。
克里斯·海斯

21
@stonyau IE8,IE9,IE10是已失效的浏览器,无法获得Microsoft的支持。IE8,IE9,IE10用户从Microsoft获得通知,他们使用的是旧的,不受支持的浏览器,并且应该期望这些内容不适用于他们。support.microsoft.com/zh-cn/kb/3123303
Lukas Liesis '16

1704

如果您知道不必担心hasOwnProperty检查,则可以非常简单地执行此操作:

Object.keys(myArray).length

23
为什么不?据我所知,这是一个标准:developer.mozilla.org/en/JavaScript/Reference/Global_Objects/...
VSYNC

104
这不是通用实现的方法,但是您可以使用此表检查哪个浏览器支持它。
aeosynth 2011年

51
不支持IE8 =不行。
ripper234

22
时间切换到firefox =不幸的是,您切换并不意味着您的网站用户将...
mdup 2012年

82
@ ripper234没有IE支持=需要填充的时间
John Dvorak

287

更新:如果您使用的是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;
};

7
_.size()是我的Meteor项目的完美解决方案,该项目具有underscore.js支持。
tokyovariable

4
我使用下划线,而这篇文章提醒我,我在本项目中使用的不够。如果处理对象,则应该有underscore.js。
jbolanos

3
下划线>(全部-['lo-dash'])
Rayjax 2014年

underscorejs,应该在js之下的东西:)
minhajul 2015年

1
@Babydead区分对象与继承对象的真实属性。developer.mozilla.org/en/docs/Web/JavaScript/Reference/…–
ripper234

56

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

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

6
Object.keys()返回一个数组,该数组仅包含那些可枚举的属性的名称。如果要使用具有ALL属性的数组,则应Object.getOwnPropertyNames()改用。见developer.mozilla.org/en/docs/Web/JavaScript/Reference/...
约翰Slegers

35

我不是JavaScript专家,但是由于Object没有length方法,因此您似乎必须遍历元素并对其进行计数:

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

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


8
将不起作用,因为它也会计算通过原型添加的方法。
Lajos Meszaros

30

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

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

@PatrickRoberts keys方法不会从原型链返回属性。那么,为什么在这里需要hasOwnProperty。也getOwnProperty将返回隐藏属性,如长度是在阵列等
穆罕默德乌默尔

24

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

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

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


我认为这是最好的解决方案,因为它不需要使用“ for”循环,如果阵列很大,则可能会很昂贵
Emeka Mbah

20

这是并且不要忘记检查该属性是否不在原型链上的方法:

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

20

只需使用它即可获得length

Object.keys(myObject).length

7
请解释您的答案与stackoverflow.com/a/6700/8632727
Patata

3
你也应该不是真的被命名你的对象myArray
巴里迈克尔多伊尔

2
@BarryMichaelDoyle我已将其更改为:)
saurabhgoyal795

很好,最好根据变量的实际名称来命名。使您的代码对其他开发人员更具可读性。
Barry Michael Doyle '18

4
在“ myArray”->“ myObject”编辑之前,此结果与第二高的答案相同。
Yunnosch

16

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

我认为那是不安全的。例如,它不能具有键为“ length”的元素,语句a1 [“ length”] =“ Hello world”; 无法存储条目。语句a1 [“ hasOwnProperty”] =“一些道具”; 完全破坏了功能
Panos Theof

3
@PanosTheof我认为如果您使用该length属性,您不希望它存储值,使用该属性的任何代码都必须确保它不会尝试针对该属性进行存储length,但是我猜想如果使用一个标准数组。覆盖hasOwnProperty任何对象很可能会产生不希望的结果。
Ally 2014年

16

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

15

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



14

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

为了公平起见,@ palmsey他是非常正确的,它们不是关联数组,它们绝对是对象:)-完成关联数组的工作。但是根据我发现的这篇相当不错的文章,关于更广泛的观点,您似乎绝对拥有它的权利:

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

但是根据所有这些,接受的答案本身不是不好的做法吗?

为对象指定原型size()函数

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


13

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

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

11

那这样的事情呢-

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

11

如果我们有哈希

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

我们可以使用键的长度(即哈希的长度)来获得长度:

keys(hash).length


2
这是一个很好的答案,但是我找不到有关此按键功能的任何文档。因此,我对跨浏览器的支持没有信心。
chim 2015年

1
不幸的是,这并不是我最初想到的那样好的答案!事实证明,键功能仅在chrome和firefox Web控制台中可用。如果将此代码放入脚本,则它将失败,并出现Uncaught ReferenceError:未定义密钥
chim


1
这与eoesynth的答案有何不同?
彼得·莫滕森

11
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

哪一个是上述3间更快
siluveru基兰·库马尔·

Object.values(myObject).length
tdjprog

我们怎么能说它Object.values(myObject).length更快呢,有没有什么例子,谢谢,@tdjprog
siluveru kiran kumar

只需在控制台中尝试:var myObject = {}; for (let i=0; i<10000000; i++) myObject[i] = i;
tdjprog

为什么Object.values(myObject).length更快,而Object.entries(myObject).length甚至在某个时间后仍不提供输出,这是什么原因? 感谢@tdjprog
siluveru kiran kumar

10

如果您使用的是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
OP尚未要求提供AngularJS版本。这不是对该问题的有效答案。
Francisco Hodge

10

最简单的方法是这样的

Object.keys(myobject).length

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


2
这似乎只是现有答案的重复。

@Pang同意,它不像其他答案那样提供任何进一步的上下文。
神秘

8

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

另请参阅此小提琴以获取演示。


8

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

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

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

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

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

// o/p 3

7

上面的一些变化是:

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

集成hasOwnProp的方式更加优雅。


6

这是詹姆斯·科根(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
Object.prototype- 馊主意。
Dziad Borowy

@tborychowski您能解释为什么吗?
Mohamad 2014年

这是一篇文章:bit.ly/1droWrG。我并不是说这不是必须要做的,只是您在执行此操作之前需要了解所有影响。
Dziad Borowy 2014年

如果要扩展内置原型或填充属性(例如,monkey-patch),请正确进行:为了向前兼容,请首先检查该属性是否存在,然后使该属性不可枚举,以便拥有自己的密钥的构造对象不会受到污染。对于方法,请使用实际 方法。我的建议:遵循这些示例这些示例演示如何添加行为与内置方法尽可能接近的方法。
user4642212

5

您可以简单地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()


3
这与eoesynth的答案有何不同?
彼得·莫滕森

这是因为它显示了如何使其成为函数和全局对象方法(更多面向对象并使用某种形式的封装);但是风神的答案没有。
神秘

如果要扩展内置原型或填充属性(例如,monkey-patch),请正确进行:为了向前兼容,请首先检查该属性是否存在,然后使该属性不可枚举,以便拥有自己的密钥的构造对象不会受到污染。对于方法,请使用实际 方法。我的建议:遵循这些示例这些示例演示如何添加行为与内置方法尽可能接近的方法。
user4642212

另外,如何编写一种“更有效”的方法?
user4642212


4

我们可以使用以下方法找到对象的长度:

Object.values(myObject).length

4

游戏有点晚了,但是实现此目的的一种好方法(仅适用于IE9 +)是在length属性上定义一个魔术吸气剂:

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

您可以像这样使用它:

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

会给1


1
除了反对原型修改的争论外,我个人从未遇到过由它引起的错误,对我来说,这是JavaScript的强项之一。
MacroMan

3

以下是James Coglan在CoffeeScript中针对那些已经放弃了JavaScript的人的答案:)

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

1
您可能想说size++ for own key of objown key在CoffeeScript中是语法糖)。使用hasOwnProperty直接对象是危险的,因为它打破时,对象实际上具有这样的属性。
Konrad Borowski

2
OP并没有要求使用CoffeeScript版本,也没有这样标记。这不是对该问题的有效答案。
Francisco Hodge
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.