编辑:更简单的复制情况;以下代码:
setInterval(function(){
var a=[10,20,30,40], i=-1;
a[-1] = 42;
while (i<10000) a[i++];
console.log(a[-1],a[4294967295]);
},100);
...产生的输出:
42 undefined
undefined 42
42 undefined
37x undefined 42
42 undefined
undefined 42
42 undefined
41x undefined 42
42 undefined
undefined 42
42 undefined
自己试试:http://jsfiddle.net/Fjwsg/
给定以下代码(或类似的代码(fiddle)):
<!DOCTYPE HTML>
<html><head><title>-1 Array Index</title></head><body>
<label>p: <input id="p" size="3"></label>
<script type="text/javascript">
var p = document.getElementById('p');
p.onkeyup = function(){
var a = "10 20 30 40".split(/\s+/);
foo(a, p.value*1);
}
function foo(a,p){
var count=a.length, i=0, x;
if (p) a[i=-1]=p;
while (i<10000) x = a[i++ % count];
console.dir(a);
}
</script>
</body></html>
当我聚焦在“p”输入框并键入1 backspace 2时,开发者控制台中出现以下内容:
![Array has index of -1 on first pass, index of 4294967295 on third pass](https://istack.dev59.com/LyUu8.webp)
4294967295
(2的32次方减1),有时会出现问题:有时开发工具会自动关闭,有时所有Safari选项卡都会冻结,需要重新启动才能恢复。奇怪的是,如果我删除这个(在这种情况下基本上没用的)while循环,我就无法重现这个问题。而且我在Chrome或Firefox上也无法重现这个问题。
有人可以解释一下可能导致这个问题的根源吗? 这是在OS X 10.7.4上使用Safari 5.1.7时发生的。
1
时,长度为4,退格键也是长度为4,当我输入2
时,长度仍然是4。它还将a[-1]
设置为相应的按键上的1和2,这似乎是不可能的。我被难住了。 - Elliot BonnevilleArray
实际上只是一个带有额外length
属性的普通Object
,该属性始终比对象中最大的数值索引大 1,并且 JS 在查找和插入期间使用类型强制转换将数值索引更改为字符串。显然,在幕后发生了更多的事情,但这意味着如果您现在保留现有内容并切换到{}
而不是[]
,则不会损失太多。无论如何,在其他语言中,不能使用负索引,因为索引是指向堆的指针。 - Andrew