Array.length gives incorrect length

后端 未结 4 1911
我在风中等你
我在风中等你 2020-12-03 16:41

If I have an array having object as values at the indices like:

var a = [];
a[21] = {};
a[90] = {};
a[13] = {};
alert(a.length); // outputs 91
相关标签:
4条回答
  • 2020-12-03 17:18

    It's because you have a[90] as largest index so the index is starting from 0 to 90 becomes 91 in length.

    And where you didn't pass the values like a[80], etc. javascript will store them as hole i.e. for eg [1, , 3, , ,90] where commas are used indicates the hole in array.

    If you try to access those values then you'll get undefined.

    0 讨论(0)
  • 2020-12-03 17:30

    That's because length gives you the next index available in the array.

    DOCS

    arrayLength

    If the only argument passed to the Array constructor is an integer between 0 and 2^32-1 (inclusive), this returns a new JavaScript array with length set to that number.

    ECMA Specifications

    Because you don't have inserted any element in the other keys than 21, 90, 13, all the remaining indexes contains undefined. DEMO

    To get actual number of elements in the array:

    var a = [];
    a[21] = {};
    a[90] = {};
    a[13] = {};
    
    var len = 0;
    
    for (var i = 0; i < a.length; i++) {
      if (a[i] !== undefined) {
        len++;
      }
    }
    document.write(len);

    Shorter version

    var a = [];
    a[21] = {};
    a[90] = {};
    a[13] = {};
    
    
    for (var i = 0, len = 0; i < a.length; i++, a[i] !== undefined && len++);
    
    
    document.write(len);

    DEMO

    EDIT

    If the array contains large number of elements, looping to get its length is not the best choice.

    As you've mentioned in the question, Object.keys(arr).length is the best solution in this case, considering that you don't have any properties added on that array. Otherwise, the length will not be what you might be expecting.(Thanks To @RobG)

    0 讨论(0)
  • 2020-12-03 17:43

    Because that's the behavior of Array.length as described in the ECMAScript spec.

    The length property of this Array object is a data property whose value is always numerically greater than the name of every deletable property whose name is an array index.

    So Array.length is always the last item's index + 1.

    0 讨论(0)
  • 2020-12-03 17:44

    The array in JavaScript is a simple zero-based structure. The array.length returns the n + 1 where n is the maximum index in an array.

    That's just how it works - when you assign 90'th element and this array's length is less than 90, it expands an array to 90 and sets the 90-th element's value. All missing values are interpreted as null.

    If you try the following code:

    var a = [];
    a[21] = {};
    a[90] = {};
    a[13] = {};
    console.log(JSON.stringify(a));
    

    You will get the following JSON:

    [null,null,null,null,null,null,null,null,null,null,null,null,null,{},null,null,null,null,null,null,null,{},null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,{}]

    Moreover, array.length is not a readonly value.
    If you set a length value less than the current, then the array will be resized:

     var arr = [1,2,3,4,5];
     arr.length = 3;
     console.log(JSON.stringify(arr));
     // [1,2,3]
    

    If you set a length value more than the current, then the array will be expanded as well:

     var arr = [1,2,3];
     arr.length = 5;
     console.log(JSON.stringify(arr));
     // [1,2,3,null,null]
    

    In case you need to assign such values, you can use JS objects.
    You can use them as associative array and assign any key-value pairs.

    var a = {};
    a[21] = 'a';
    a[90] = 'b';
    a[13] = 'c';
    a['stringkey'] = 'd';
    a.stringparam = 'e'; // btw, a['stringkey'] and a.stringkey is the same
    
    console.log(JSON.stringify(a)); 
    // returns {"13":"c","21":"a","90":"b","stringkey":"d","stringparam":"e"}
    
    console.log(Object.keys(a).length);
    // returns 5
    
    0 讨论(0)
提交回复
热议问题