JavaScript 数组中的负索引是否会影响数组长度?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13618571/
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
Should negative indexes in JavaScript arrays contribute to array length?
提问by me_digvijay
In javascript I define an array like this
在javascript中我定义了一个这样的数组
var arr = [1,2,3];
also I can do
我也可以
arr[-1] = 4;
Now if I do
现在如果我这样做
arr = undefined;
I also lose the reference to the value at arr[-1].
我也失去了对arr[-1]值的引用。
SO for me logically it seems like arr[-1] is also a part of arr.
所以对我来说逻辑上似乎 arr[-1] 也是arr的一部分。
But when I do following (without setting arr to undefined)
但是当我执行以下操作时(没有将 arr 设置为未定义)
arr.length;
It returns 3not 4;
它返回3而不是4;
So my point is if the arrays can be used with negative indexes,these negative indexes should also be a part of their length**. I don't know may be I am wrong or I may be missing some concept about arrays.
所以我的观点是,如果数组可以与负索引一起使用,这些负索引也应该是它们长度的一部分**。我不知道可能是我错了,或者我可能遗漏了一些关于数组的概念。
回答by Andrew Whitaker
SO for me logically it seems like arr[-1] is also a part of arr.
所以对我来说逻辑上似乎 arr[-1] 也是 arr 的一部分。
Yes it is, but not in the way you think it is.
是的,但不是你认为的那样。
You can assign arbitrary properties to an array (just like any other Object in JavaScript), which is what you're doing when you "index" the array at -1and assign a value. Since this is not a member of the array and just an arbitrary property, you should not expect lengthto consider that property.
您可以为数组分配任意属性(就像 JavaScript 中的任何其他对象一样),这就是您在“索引”数组-1并分配值时所做的。由于这不是数组的成员而只是一个任意属性,因此您不应期望length考虑该属性。
In other words, the following code does the same thing:
换句话说,下面的代码做同样的事情:
?var arr = [1, 2, 3];
?arr.cookies = 4;
alert(arr.length) // 3;
回答by nnnnnn
The lengthproperty will return a number one higher than the highest assigned "index", where Array "indexes" are integers greater than or equal to zero. Note that JS allows "sparse" arrays:
该length属性将返回一个比最高分配的“索引”高一的数字,其中数组“索引”是大于或等于零的整数。请注意,JS 允许“稀疏”数组:
var someArray = [];
someArray[10] = "whatever";
console.log(someArray.length); // "11"
Of course if there are no elements then lengthis 0. Note also that the lengthdoesn't get updated if you use deleteto remove the highest element.
当然,如果没有元素,则length是0。另请注意,length如果您用于delete删除最高元素,则不会更新。
But arrays are objects, so you can assign properties with other arbitrary property names including negative numbers or fractions:
但是数组是对象,因此您可以使用其他任意属性名称(包括负数或分数)分配属性:
someArray[-1] = "A property";
someArray[3.1415] = "Vaguely Pi";
someArray["test"] = "Whatever";
Note that behind the scenes JS converts the property names to strings even when you supply a number like -1. (The positive integer indexes also become strings, for that matter.)
请注意,即使您提供像-1. (正整数索引也变成字符串,就此而言。)
Array methods, like .pop(), .slice(), etc., only work on the zero-or-higher integer "indexes", not on other properties, so lengthis consistent on that point.
数组方法,如.pop()、.slice()等,仅适用于零或更高的整数“索引”,而不适用于其他属性,因此length在这一点上是一致的。
回答by Sampson
Note that when you use a position (or 0) index, values are placed within the array:
请注意,当您使用位置(或 0)索引时,值将放置在数组中:
var array = [];
array[0] = "Foo";
array[1] = "Bar";
// Result: ["Foo", "Bar"]
// Length: 2
This is not the case when you add non-index values (not 0-9+):
添加非索引值(不是 0-9+)时,情况并非如此:
var array = [];
array[0] = "Foo";
array[1] = "Bar";
array[-1] = "Fizzbuzz"; // Not a proper array index - kill it
// Result: ["Foo", "Bar"]
// Length: 2
Values are only placed in the array when you play by the rules. When you don't, they aren't accepted. They are however accepted on the Array object itself, which is the case with just about anything in JavaScript. Even though ["Foo", "Bar"]are the only values in our array, we can still access "Fizzbuzz":
当您按照规则进行操作时,值仅放置在数组中。当你不这样做时,他们不会被接受。然而,它们在 Array 对象本身上被接受,JavaScript 中的任何东西都是这种情况。即使["Foo", "Bar"]是我们数组中唯一的值,我们仍然可以访问"Fizzbuzz":
array[-1]; // "Fizzbuzz"
But note again that this isn't part of the array values, since its "index" isn't valid. It was instead added onto the array as just another member. We could access other array members in the same fashion:
但再次注意,这不是数组值的一部分,因为它的“索引”无效。相反,它只是作为另一个成员添加到数组中。我们可以以同样的方式访问其他数组成员:
array["pop"]; // function pop() { [native code] }
Note here that we're accessing the popmethod on the array, which informs us that this contains native code. We're not accessing any of the array values with a key of "pop", but rather a member on the array object itself. We can further confirm this by cycling over the public members of the object:
请注意,我们正在访问pop数组上的方法,它告诉我们它包含本机代码。我们不是使用“pop”键访问任何数组值,而是访问数组对象本身的成员。我们可以通过循环遍历对象的公共成员来进一步确认这一点:
for (var prop in array)
console.log(prop, array[prop]);
Which spits out the following:
其中吐出以下内容:
0 Foo
1 Bar
-1 Fizzbuzz
So again, it's onthe object, but it's not inthe array.
如此反复,这是对的对象,但它不是在该阵列。
Awesome question! Caused me to do a double-take for sure.
很棒的问题!让我肯定做了双重拍摄。
回答by David Sherret
If you really want negative indexes and other indexes to be included in the length, then create the functionality yourself:
如果您确实希望将负索引和其他索引包含在长度中,请自行创建功能:
function getExtendedArray() {
var a = [];
Object.defineProperty(a, 'totalLength', {
get : function() { return Object.keys(a).length; }
});
return a;
}
Then for example:
然后例如:
var myArray = getExtendedArray();
console.log(myArray.totalLength); // 0
myArray.push("asdf");
myArray[-2] = "some string";
myArray[1.7777] = "other string";
console.log(myArray.totalLength); // 3
回答by Tony R
Arrays in JavaScript are actually objects. They are simply prototyped from the Array constructor.
JavaScript 中的数组实际上是对象。它们只是从 Array 构造函数中创建原型。
Array indices are actually keys in a hashmap, and all keys are converted to strings. You can create any key (i.e. "-1"), but the methods on Array are tailored to act like an array. So lengthisn't the size of the object, it's rather only guaranteed to be larger than the largest integer index. Similarly, printing arrwill only list values with integer keys >= 0.
数组索引实际上是哈希图中的键,所有键都转换为字符串。您可以创建任何键(即“-1”),但 Array 上的方法被定制为像数组一样工作。所以length不是对象的大小,而是只保证大于最大的整数索引。同样,打印arr只会列出整数键 >= 0 的值。
回答by HynekS
Arrayis just a special kind of Objectin JS. There is a special syntax, which is good, because it allows us to work with them effectively. Imagine how tedious would it be to write an array literal that way:
Array只是JS 中一种特殊的Object。有一种特殊的语法,这很好,因为它允许我们有效地使用它们。想象一下,以这种方式编写数组文字是多么乏味:
const array = {{0: 'foo'}, {1: 'bar'}, {2: 'baz}} //etc...
But there are objectsnevertheless. So if you do:
但是还是有对象的。所以如果你这样做:
const myArray = [42, 'foo', 'bar', 'baz'];
myArray[-1] = 'I am not here';
myArray['whatever'] = 'Hello World';
Those non-integer properties will be attached to an object (which array is), but there are not accessible by some native methods like Array.length.
这些非整数属性将附加到一个对象(数组是哪个),但某些本机方法(如Array.length.
You can assume that the native 'length' method is a getter which counts all properties (and indexes areproperties, while values are the actual values) convertible to positive integer or zero. Something like this pseudo-implementation:
您可以假设本机 'length' 方法是一个 getter,它计算所有可转换为正整数或零的属性(索引是属性,而值是实际值)。像这样的伪实现:
Due to specs, the native lenghtmethod – as a getter(exampleArray.length) – will check all 'nonnegative integer less than 232' keys, get the greates one and return its numeric value + 1.
由于规范,本机lenght方法 - 作为getter( exampleArray.length) - 将检查所有“小于 2 32的非负整数”键,获取最大值并返回其数值 + 1。
As a setter(exampleArray.length = 42), it will either create some empty slots for 'missing' indices if the given length is greater than the actual number of nonnegative integer keys, or delete all nonnegative integer keys (and their values) which are not greater then the given length.
作为setter( exampleArray.length = 42),如果给定的长度大于非负整数键的实际数量,它将为“缺失”索引创建一些空槽,或者删除所有不大于该索引的非负整数键(及其值)给定长度。
The pseudo-implementation:
伪实现:
const myArray = {
'-1': 'I am not here', // I have to use apostrophes to avoid syntax error
0: 42,
1: 'foo',
2: 'bar',
3: 'baz',
whatever: 'Hello World',
get myLength() {
let highestIndex = -1;
for (let key in this) {
let toInt = parseInt(key, 10);
if (!Number.isNaN(toInt) && toInt > -1) {
// If you're not an integer, that's not your business! Back off!
if (toInt > highestIndex) highestIndex = toInt;
}
}
return highestIndex + 1;
},
set myLength(newLength) {
/* This setter would either:
1) create some empty slots for 'missing' indices if the given length is greater than the actual number of non-negative-integer keys
2) delete all non-negative-integer keys (and their values) which are not greater then the given length.
*/
}
}
console.log(myArray.myLength); // 4
myArray[9] = 'foobar';
console.log(myArray.myLength); // 10
回答by ktilcu
According to MDN:
根据 MDN:
The value of the length property is an integer with a positive sign and a value less than 2 to the 32 power (232)
length 属性的值是一个带正号的整数,其值小于 2 的 32 次方 (232)
In Javascript you can set a property on any object you create.
在 Javascript 中,您可以在您创建的任何对象上设置属性。
var array = new Array();
array = [1,2,3];
array["boom"] = "pow";
In the same way when you set a negative index it stores it as a property on the array rather than part of the index.
以同样的方式,当您设置负索引时,它将其存储为数组上的属性而不是索引的一部分。
array[-1] = "property does not add to array length";
This is why the length doesn't reflect it but a for..in loop shows it.
这就是为什么长度不反映它但 for..in 循环显示它的原因。
回答by Ashan
When you use non-positive or non numeric indexes the array behaves as an associative array which has key-value pairs.
当您使用非正或非数字索引时,数组表现为具有键值对的关联数组。
To iterate through the array you can use
要遍历数组,您可以使用
for(var index in myArray) {
document.write( index + " : " + myArray[index] + "<br />");
}

