JavaScript对象的长度

Gar*_*son 2224 javascript javascript-objects

如果我有一个JavaScript对象,请说

const myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
Run Code Online (Sandbox Code Playgroud)

是否有内置或接受的最佳实践方法来获取此对象的长度?

小智 2448

最强大的答案(即捕获您尝试做的意图,同时导致最少的错误)将是:

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);
Run Code Online (Sandbox Code Playgroud)

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


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

var size = Object.keys(myObj).length;
Run Code Online (Sandbox Code Playgroud)

因为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
Run Code Online (Sandbox Code Playgroud)

  • 为什么每个人都忽略了这一点:`Object.keys(obj).length` (124认同)
  • @Tres - 如果有人在不知道你已经在代码中的某个地方宣布它的情况下来到'size'属性,你的代码就会被破坏,所以总是值得检查它是否已经定义 (63认同)
  • @MuhammadUmer可能是因为当写这个答案时,该方法甚至不存在.即使在今天,使用它可能还需要旧浏览器的polyfill. (29认同)
  • @stonyau IE8,IE9,IE10是死的浏览器,没有得到微软的支持.IE8,IE9,IE10用户收到来自Microsoft的通知,他们使用旧的,不受支持的浏览器,并且应该期望这些内容对他们不起作用.https://support.microsoft.com/en-us/kb/3123303 (21认同)
  • @vsync你是对的.应该总是实施必要的健全性检查:) (18认同)
  • @James Coglan为什么要在Object类中声明函数而不仅仅是常规函数?即函数getSize(obj){...}? (3认同)
  • @alexserver我猜他只是保持适当的结构.此函数返回对象的大小,因此将其作为Object的扩展是有意义的.保持代码清洁和可维护. (3认同)
  • @Przemek我不明白你的意思。`Object.keys(new Date())。length`给出'0',`x = new Date(); Object.keys(x).length`也为0。 (2认同)

aeo*_*nth 1627

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

Object.keys(myArray).length
Run Code Online (Sandbox Code Playgroud)

  • 它不是普遍*实现的*方法,但您可以使用[此表](http://kangax.github.com/es5-compat-table/)检查哪个浏览器支持它. (103认同)
  • @ ripper234没有IE支持=时间到polyfill (77认同)
  • 没有IE8支持=没有去. (49认同)
  • 为什么不?据我所知,这是一个标准:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys (23认同)
  • 时间切换到firefox =不幸的是,你切换并不意味着你的网站的用户会...... (22认同)
  • @ ripper234谁在乎IE,没有人应该关心IE unstandards,只有标准.用户想要使用IE然后他们将无法浏览我的网站我不再关心.开发人员不应该填充不是由"开发者"制定的标准 (19认同)
  • @ ripper234这取决于您的要求. (10认同)
  • 至少,它在`node.js`服务器端工作:)谢谢你的回答. (10认同)
  • 根据该表,IE8支持4/34的"标准".哇. (8认同)
  • `if(typeof Object.keys!='function'){Object.keys = function(obj){var ret = []; for(var x in obj){if(obj.hasOwnProperty(x)){ret [ret.length] = x; 返回; } (7认同)
  • @albanx这种态度不会让你在网络开发方面走得更远.网站是为访问者而不是为开发者而制作的. (7认同)
  • 规范说,keys()方法只返回对象自己的属性的名称,因此使用此方法将避免hasOwnProperty检查. (4认同)
  • 遗留 IE 的伟大 polyfill:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object (2认同)

rip*_*234 277

更新:如果您正在使用Underscore.js(推荐它,它很轻!),那么您可以这样做

_.size({one : 1, two : 2, three : 3});
=> 3
Run Code Online (Sandbox Code Playgroud)

如果没有,并且你不想因为某种原因搞乱对象属性,并且已经在使用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;
};
Run Code Online (Sandbox Code Playgroud)

  • `_.size()`是我的[Meteor](http://www.meteor.com/)项目的完美解决方案,该项目有underscore.js支持. (7认同)
  • 我使用下划线,这篇文章只是提醒我,我在这个项目中没有使用它.如果处理对象,则应该使用underscore.js. (4认同)
  • 下划线>(全部 - ['lo-dash']) (3认同)

Joo*_*oon 53

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

这比接受的答案更好,因为它使用本机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;
Run Code Online (Sandbox Code Playgroud)

  • `Object.keys()`返回一个数组,该数组只包含那些可枚举的属性的名称.如果你想要一个包含ALL属性的数组,你应该使用`Object.getOwnPropertyNames()`.请参阅https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys (6认同)

jj3*_*j33 34

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

var element_count = 0;
for (e in myArray) {  if (myArray.hasOwnProperty(e)) element_count++; }
Run Code Online (Sandbox Code Playgroud)

@palmsey:为了公平起见,JavaScript文档实际上明确地将这种类型的Object变量称为"关联数组".

  • 无法工作,因为它也会计算方法,通过原型添加. (6认同)

Tam*_*war 34

最简单的是

Object.keys(myObject).length
Run Code Online (Sandbox Code Playgroud)

  • 这似乎只是[此现有答案](/sf/answers/3382334931/)的重复。 (3认同)

ven*_*668 30

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

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


Dan*_*Man 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
Run Code Online (Sandbox Code Playgroud)

如果始终使用add方法,则length属性将是正确的.如果您担心您或其他人忘记使用它,您也可以将其他人发布的属性计数器添加到长度方法中.

当然,您总是可以覆盖这些方法.但即使你这样做,你的代码可能会明显失败,使调试变得容易.;)


sol*_*... 21

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

const myObject = {};
console.log(Object.values(myObject).length);
Run Code Online (Sandbox Code Playgroud)


doe*_*man 19

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

var element_count = 0;
for(var e in myArray)
    if(myArray.hasOwnProperty(e))
        element_count++;
Run Code Online (Sandbox Code Playgroud)


sau*_*795 18

只需使用它来获得length:

Object.keys(myObject).length
Run Code Online (Sandbox Code Playgroud)

  • 请解释您的答案与/sf/answers/469031/的不同之处 (6认同)
  • 和过去的回复一样。 (4认同)
  • 在“ myArray”->“ myObject”编辑之前,此结果与第二高的答案相同。 (3认同)
  • 您也不应该真正在命名对象“ myArray”。 (2认同)
  • @BarryMichaelDoyle我已经改变了:) (2认同)

小智 17

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

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

console.log(Object.keys(myObject).length); //3
Run Code Online (Sandbox Code Playgroud)


Ran*_*ner 17

使用该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
Run Code Online (Sandbox Code Playgroud)


All*_*lly 16

这是一个完全不同的解决方案,只适用于更现代的浏览器(IE9 +,Chrome,Firefox 4 +,Opera 11.60 +,Safari 5.1+)

jsFiddle

设置Associative Array类

/**
 * @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;
    }
});
Run Code Online (Sandbox Code Playgroud)

现在您可以使用以下代码...

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

  • @PanosTheof我不认为如果你使用`length`属性你想要它存储值,任何使用它的代码都必须确保它不会尝试存储`length`,但我想这会如果它也是标准阵列也是一样的.在任何对象上覆盖`hasOwnProperty`很可能会产生不希望的结果. (3认同)

Jān*_*ris 15

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


Mah*_*rni 15

使用:

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


Pol*_*nby 14

@palmsey:为了公平对待OP,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>
Run Code Online (Sandbox Code Playgroud)

我不认为答案应该是被接受的答案,因为如果你在同一个执行上下文中运行任何其他代码,它就不能被信任.要以健壮的方式做到这一点,你肯定需要在myArray中定义size方法,并在迭代它们时检查成员的类型.


Gio*_* PY 14

<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>
Run Code Online (Sandbox Code Playgroud)

这对我有用:

var size = Object.keys(myObj).length;
Run Code Online (Sandbox Code Playgroud)


小智 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--; }}
}
Run Code Online (Sandbox Code Playgroud)


小智 11

如果我们有哈希

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

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

键(散列).长度

  • 这是一个很好的答案,但是我找不到有关此按键功能的任何文档。因此,我对跨浏览器的支持没有信心。 (2认同)
  • 不幸的是,这并不像我最初想的那样好!事实证明,keys 功能仅在 chrome 和 firefox 网络控制台中可用。如果您将此代码放入脚本中,它将失败并显示 Uncaught ReferenceError: keys is not defined (2认同)

pcn*_*ate 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;
 }
})
Run Code Online (Sandbox Code Playgroud)

用法

在你的控制器中:

$scope.filterResult = $filter('lengthOfObject')($scope.object)
Run Code Online (Sandbox Code Playgroud)

或者在你看来:

<any ng-expression="object | lengthOfObject"></any>
Run Code Online (Sandbox Code Playgroud)

  • OP没有要求AngularJS版本.这不是问题的有效答案. (4认同)

Ori*_*iol 10

如果需要一个暴露其大小的关联数据结构,最好使用地图而不是对象.

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


tdj*_*rog 9

var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
Run Code Online (Sandbox Code Playgroud)
  1. Object.values(myObject的).长度
  2. Object.entries(myObject的).长度
  3. Object.keys(myObject的).长度


小智 9

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

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

// o/p 3
Run Code Online (Sandbox Code Playgroud)

  • 另外,它与以前的答案有什么不同,例如[shaheb的答案](/sf/ask/365641/#57839252)? (2认同)

Joh*_*ers 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;
}
Run Code Online (Sandbox Code Playgroud)

如何使用这个特定的功能:

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
Run Code Online (Sandbox Code Playgroud)

另见这个小提琴的演示.


小智 8

最简单的方法是这样的

Object.keys(myobject).length
Run Code Online (Sandbox Code Playgroud)

myobject是你想要的长度的对象

  • 这似乎只是[此现有答案](/sf/answers/3382334931/)的重复。 (2认同)

小智 7

上述部分内容的变体是:

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

这是集成hasOwnProp的更优雅的方式.


She*_*zod 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;
Run Code Online (Sandbox Code Playgroud)

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

  • `Object.prototype` - 坏主意. (6认同)

Pia*_*M4n 5

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

  • 与[aeosynth的答案](http://stackoverflow.com/questions/5223/length-of-a-javascript-object-or-associative-array/5527037#5527037)有何不同? (3认同)

Mys*_*cal 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()
Run Code Online (Sandbox Code Playgroud)

  • 与[aeosynth的答案](http://stackoverflow.com/questions/5223/length-of-a-javascript-object-or-associative-array/5527037#5527037)有何不同? (3认同)