javascript对象的长度

Length of a JavaScript object

如果我有一个javascript对象,比如

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

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


最有力的答案(即捕捉到您在导致最少错误的同时尝试做的事情的意图)是:

1
2
3
4
5
6
7
8
9
10
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添加内容,因为它可以破坏各种库中的枚举。不过,向对象添加方法通常是安全的。

以下是截至2016年的最新消息,以及ES5及以后的广泛部署。对于IE9+和所有其他支持ES5+的现代浏览器,您可以使用Object.keys(),因此上面的代码只是:

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

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

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

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

Object.keysObject.getOwnPropertyNames不适用于符号属性。要退货,您需要使用Object.getOwnPropertySymbols

1
2
3
4
5
6
7
8
9
10
11
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


如果你知道你不必担心hasOwnProperty支票,你可以很简单地做到:

1
Object.keys(myArray).length


更新:如果您使用的是underline.js(推荐,它是轻量级的!)那么你就可以

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

如果不是,并且您不想因为任何原因而乱搞对象属性,并且已经在使用jquery,则插件同样可以访问:

1
2
3
4
5
6
7
8
$.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(如果存在)。因此,它是所有现代浏览器中速度最快的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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专家,但看起来您必须循环遍历元素并计算它们,因为对象没有长度方法:

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

@palmsey:公平地说,javascript文档实际上以这种方式明确地将使用类型为object的变量称为"关联数组"。


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

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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方法的属性计数器。

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


最简单的是

1
Object.keys(myObject).length


以下是如何并且不要忘记检查属性是否不在原型链上:

1
2
3
4
var element_count = 0;
for(var e in myArray)
    if(myArray.hasOwnProperty(e))
        element_count++;


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

参见JSFIDLE

设置关联数组类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
 * @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;
    }
});

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

1
2
3
4
5
var a1 = new AssociativeArray();
a1["prop1"] ="test";
a1["prop2"] = 1234;
a1["prop3"] ="something else";
alert("Length of array is" + a1.length);


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


只需使用这个来获取length

1
Object.keys(myObject).length


用途:

1
2
3
4
5
6
var myArray = new Object();
myArray["firstname"] ="Gareth";
myArray["lastname"] ="Simpson";
myArray["age"] = 21;
obj = Object.keys(myArray).length;
console.log(obj)


@palmsey: In fairness to the OP, the javascript docs actually explicitly refer to using variables of type Object in this manner as"associative arrays".

< /块引用>

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

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

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

Specify a prototype size() function for Object

< /块引用>

如果在object.prototype中添加了其他内容,则建议的代码将失败:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script type="text/javascript">
Object.prototype.size = function () {
&nbsp; var len = this.length ? --this.length : -1;
&nbsp; &nbsp; for (var k in this)
&nbsp; &nbsp; &nbsp; len++;
&nbsp; return len;
}
Object.prototype.size2 = function () {
&nbsp; var len = this.length ? --this.length : -1;
&nbsp; &nbsp; for (var k in this)
&nbsp; &nbsp; &nbsp; len++;
&nbsp; 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());

我认为答案不应该是可接受的,因为如果在同一执行上下文中运行任何其他代码,那么它就不可能工作。要以一种健壮的方式完成这项工作,您当然需要在myarray中定义size方法,并在迭代成员时检查成员的类型。


如果我们有大麻

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

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

keys(hash).length


像这样的东西怎么样--

1
2
3
4
5
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--; }}
}

如果您使用的是AngularJS 1.x,那么您可以通过创建一个过滤器并使用其他示例(如以下)中的代码来执行AngularJS方法:

1
2
3
4
5
6
7
8
9
10
// 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;
 }
})

用法

在控制器中:

1
$scope.filterResult = $filter('lengthOfObject')($scope.object)

或者在你看来:

1
</any>


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

1
2
3
4
5
var myMap = new Map();
myMap.set("firstname","Gareth");
myMap.set("lastname","Simpson");
myMap.set("age", 21);
myMap.size; // 3

上面的一些变化是:

1
2
3
4
5
6
7
var objLength = function(obj){    
    var key,len=0;
    for(key in obj){
        len += Number( obj.hasOwnProperty(key) );
    }
    return len;
};

这是一种更优雅的方法来集成hasownprop。


1
2
3
4
5
6
7
myObj = {"key1" :"Hello","key2" :"Goodbye"};
var size = Object.keys(myObj).length;
console.log(size);


<p id="myObj">The number of keys in myObj are: document.write(size)
</p>

这对我很有用:

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

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

  • 运行Object.keys()以获取一个数组,该数组只包含那些可枚举的属性的名称;如果您还希望包含那些不可枚举的属性的名称,则运行Object.getOwnPropertyNames()
  • 获取该数组的.length属性。
  • 如果需要多次执行此操作,可以将此逻辑包装在函数中:

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

    如何使用此特定功能:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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

    另请参见此小提琴的演示。


    1
    2
    3
    4
    var myObject = new Object();
    myObject["firstname"] ="Gareth";
    myObject["lastname"] ="Simpson";
    myObject["age"] = 21;
  • 对象.值(myObject).length
  • 对象.条目(myObject).length
  • 对象.键(myObject).length

  • 这是詹姆斯·科根答案的另一个版本。不要传递参数,只需将对象类原型化并使代码更清晰。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    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;

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


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    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()


    最简单的方法是这样

    1
    Object.keys(myObject).length

    其中myObject是所需长度的对象


    您可以始终执行Object.getOwnPropertyNames(myObject).length,以获得与正常数组[].length相同的结果。


    下面是一个版本的詹姆斯·科格兰(JamesCoglan)在《咖啡描述》(Coffeescript)中对那些放弃了纯javascript的人的回答:)

    1
    2
    3
    4
    Object.size = (obj) ->
      size = 0
      size++ for own key of obj
      size


    财产

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Object.defineProperty(Object.prototype, 'length', {
        get: function () {
            var size = 0, key;
            for (key in this)
                if (this.hasOwnProperty(key))
                    size++;
            return size;
        }
    });

    使用

    1
    2
    3
    4
    var o = {a: 1, b: 2, c: 3};
    alert(o.length); // <-- 3
    o['foo'] = 123;
    alert(o.length); // <-- 4

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

    1
    Object.values(myObject).length

    虽然比游戏晚了一点,但实现这一点的一个好方法(仅限IE9+)是在length属性上定义一个魔力getter:

    1
    2
    3
    4
    5
    Object.defineProperty(Object.prototype,"length", {
        get: function () {
            return Object.keys(this).length;
        }
    });

    你可以这样使用它:

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

    会给1


    和大多数javascript问题一样,有很多解决方案。您可以扩展对象,使其更好或更差地工作,就像许多其他语言的字典(+一流公民)。这没什么错,但另一个选择是构造一个满足您特定需求的新对象。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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());


    简单解决方案:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
      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.

    对象继承时,Object.keys不返回权利结果。要正确计算对象属性,包括继承的属性,请使用for-in,例如通过以下函数(相关问题)

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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)");


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

    代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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;
    };

    数据实例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 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;

    用法

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

    在我看来,最好的答案是,if (obj.hasOwnProperty(key))控制是多余的。它总是返回true

    1
    2
    3
    4
    5
    6
    7
    Object.size = function(obj) {
        var size = 0, key;
        for (key in obj) {
         size++;
       }
       return size;
    };


    1
    2
    3
    4
    5
    6
    7
    8
    var myObject = new Object();
    myObject["firstname"] ="Gareth";
    myObject["lastname"] ="Simpson";
    myObject["age"] = 21;

    var size = JSON.stringify(myObject).length;

    document.write(size);

    1
    JSON.stringify(myObject)