Javascript Array.length 给出的长度不正确
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31065075/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Array.length gives incorrect length
提问by Muhammad Talha Akbar
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
I have found a workaround to get the actual length:
我找到了一种解决方法来获得实际长度:
function getLength(arr) {
return Object.keys(arr).length;
}
var a = [];
a[21] = {};
a[90] = {};
a[13] = {};
alert(getLength(a));
But, why does JS gives incorrect length when objects are stored at random indices?It just adds 1 to the largest index found on an array. Like in the above example, 90 was the largest index. It just adds 1 and gives 91 as output. Demonstration
但是,当对象以随机索引存储时,为什么 JS 给出的长度不正确?它只是在数组上找到的最大索引上加 1。与上面的示例一样,90 是最大的索引。它只是加 1 并给出 91 作为输出。示范
采纳答案by Tushar
That's because length
gives you the next index
available in the array.
那是因为length
为您index
提供了数组中的下一个可用。
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.
如果传递给 Array 构造函数的唯一参数是 0 到 2^32-1(含)之间的整数,则返回一个长度设置为该数字的新 JavaScript 数组。
Because you don't have inserted any element in the other keys than 21, 90, 13, all the remaining indexes contains undefined
. DEMO
因为您没有在 21、90、13 之外的其他键中插入任何元素,所以所有剩余的索引都包含undefined
. 演示
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);
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)
正如您在问题中提到的Object.keys(arr).length
,考虑到您没有在该数组上添加任何属性,这是这种情况下的最佳解决方案。否则,length
将不会是您所期望的。(感谢@RobG)
回答by Yeldar Kurmangaliyev
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.
JavaScript 中的数组是一个简单的从零开始的结构。的array.length
返回n + 1
,其中n
是在阵列的最大索引。
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
.
这就是它的工作原理 - 当您分配第 90 个元素并且该数组的长度小于 90 时,它将数组扩展为 90 并设置第 90 个元素的值。所有缺失值都被解释为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:
您将获得以下 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,{}]
[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 lessthan the current, then the array will be resized:
此外,array.length
不是只读值。
如果您设置的length
值小于当前值,则数组将被调整大小:
var arr = [1,2,3,4,5];
arr.length = 3;
console.log(JSON.stringify(arr));
// [1,2,3]
If you set a length
value morethan the current, then the array will be expanded as well:
如果设置了length
值更比当前,那么阵列将被扩大,以及:
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.
如果您需要分配这样的值,您可以使用 JS 对象。
您可以将它们用作关联数组并分配任何键值对。
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
回答by Cory Danielson
Because that's the behavior of Array.length as described in the ECMAScript spec.
因为这是ECMAScript 规范中描述的 Array.length 的行为。
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.
此 Array 对象的 length 属性是一个数据属性,其值在数字上始终大于名称为数组索引的每个可删除属性的名称。
So Array.length is always the last item's index + 1.
所以 Array.length 总是最后一项的索引 + 1。
回答by Bhojendra Rauniyar
It's because you have a[90] as largest index so the index is starting from 0 to 90 becomes 91 in length.
这是因为你有一个 [90] 作为最大的索引,所以索引从 0 到 90 的长度变成了 91。
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.
并且您没有传递像 a[80] 等值的地方。javascript 会将它们存储为孔,即例如[1, , 3, , ,90]
,使用逗号的地方表示数组中的孔。
If you try to access those values then you'll get undefined
.
如果您尝试访问这些值,那么您将获得undefined
.