JavaScript数组中的负向索引是否会影响数组长度?

在JavaScript中,我定义了一个这样的数组

var arr = [1,2,3]; 

我也可以做

 arr[-1] = 4; 

现在,如果我这样做

 arr = undefined; 

我也失去了对arr [-1]值的引用。

所以对我来说,逻辑上看来,arr [-1]也是arr的一部分。

但是当我遵循(没有设置ARR未定义)

 arr.length; 

它返回3而不是4 ;

所以我的观点是如果数组可以用于负指数,这些负指数也应该是它们长度的一部分**。 我不知道可能是我错了,或者我可能会错过关于数组的一些概念。

所以对我来说,逻辑上看来,arr [-1]也是arr的一部分。

是的,但不是你认为的方式。

你可以为数组指定任意的属性(就像JavaScript中的任何其他对象一样),当你在-1处对数组“索引”并赋值时,这就是你正在做的事情。 由于这不是数组的成员,只是一个任意的属性,所以你不应该指望length来考虑这个属性。

换句话说,下面的代码做同样的事情:

 ​var arr = [1, 2, 3]; ​arr.cookies = 4; alert(arr.length); 

length属性将返回比最高分配的“索引”更高的数字,其中数组“索引”是大于或等于零的整数。 请注意,JS允许“稀疏”数组:

 var someArray = []; someArray[10] = "whatever"; console.log(someArray.length); // "11" 

当然,如果没有元素,那么length0 。 另请注意,如果使用delete删除最高元素,则length不会更新。

但是数组是对象,因此您可以使用其他任意属性名称(包括负数或分数)来分配属性:

 someArray[-1] = "A property"; someArray[3.1415] = "Vaguely Pi"; someArray["test"] = "Whatever"; 

请注意,即使在提供像-1这样的数字的情况下,JS也会将属性名称转换为string。 (正整数索引也成为string,就此而言)。

.pop() .slice()等数组方法只能在零或更高的整数“索引”上工作,而不能在其他属性上工作,所以length在这一点上是一致的。

请注意,当您使用位置(或0)索引时,值将放置在数组中:

 var array = []; array[0] = "Foo"; array[1] = "Bar"; // Result: ["Foo", "Bar"] // Length: 2 

添加非索引值(不是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 

按规则玩时,值只能放在数组中。 当你不这样做时,他们不被接受。 然而,它们被接受在Array对象本身上,JavaScript中的任何东西都是这种情况。 即使["Foo", "Bar"]是我们数组中唯一的值,我们仍然可以访问"Fizzbuzz"

 array[-1]; // "Fizzbuzz" 

但请注意,这不是数组值的一部分,因为它的“索引”是无效的。 它只是作为另一个成员被添加到数组中。 我们可以用同样的方式访问其他数组成员:

 array["pop"]; // function pop() { [native code] } 

请注意,我们正在访问数组中的pop方法,它告诉我们这包含本机代码。 我们不是使用“pop”键访问任何数组值,而是数组对象本身的成员。 我们可以通过循环对象的公众成员来进一步确认:

 for (var prop in array) console.log(prop, array[prop]); 

其中吐出以下内容:

  0 Foo 1 Bar -1 Fizzbuzz 

再次,它 对象上 ,但它不在数组中

真棒问题! 让我做了一个确定的双重考虑。

如果你真的想要负数索引和其他索引被包含在长度中,那么你自己创build这个function:

 function getExtendedArray() { var a = []; Object.defineProperty(a, 'totalLength', { get : function() { return Object.keys(a).length; } }); return a; } 

然后例如:

 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 

JavaScript中的数组实际上是对象。 他们只是从数组构造函数原型。

数组索引实际上是散列表中的键,所有键都被转换为string。 你可以创build任何键(即“-1”),但是Array上的方法被定制为像一个数组一样。 所以length不是对象的大小,而只是保证大于最大的整数索引。 同样,打印arr将只列出整数键> = 0的值。

更多信息在这里。

根据MDN:

length属性的值是一个带正号的整数,其值小于2的32次方(232)

在Javascript中,您可以在您创build的任何对象上设置属性。

 var array = new Array(); array = [1,2,3]; array["boom"] = "pow"; 

以相同的方式,当你设置一个负数索引时,它把它作为数组的一个属性存储,而不是索引的一部分。

 array[-1] = "property does not add to array length"; 

这就是为什么长度不能反映它,但for..in循环显示它。

在使用非正数或非数字索引时,数组的行为与具有键 – 值对的关联数组相同。

遍历可以使用的数组

 for(var index in myArray) { document.write( index + " : " + myArray[index] + "<br />"); }