7

編集:より単純な再現ケース; 次のコード:

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/


(元の質問は次のとおりです)

次のコード(またはそのようなコード(フィドル) )が与えられます:

<!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
配列のインデックスは、最初のパスで-1、3番目のパスで4294967295です。

4294967295(2 32-1 )のインデックスが表示されると、状況が「悪化」し始めることがあります。開発者ツールが自動的に閉じたり、すべてのSafariタブがフリーズして、回復するために再起動が必要になることがあります。

奇妙なことに、whileループ(この場合はほとんど役に立たない)を削除すると、これを再現できません。そして、ChromeやFirefoxでこれを再現することはできません。

誰かがこの問題の根本にある可能性があるものに光を当てることができますか?

これは、OSX10.7.4のSafari5.1.7で発生しています。

4

2 に答える 2

3

負のインデックスを使用すると、未定義の動作が発生する可能性があります。

ECMAScriptのドキュメントによると、特定の値pは、次の場合にのみ配列インデックスになります。

(p >>> 0 === p) && (p >>> 0 !== Math.pow(2, 32) - 1)

あなたの場合:

# -1 >>> 0
4294967295
# Math.pow(2, 32) - 1
4294967295

編集

上記のテストに失敗した場合は、またはpのような通常のオブジェクトプロパティとして扱う必要があります。とはいえ、結局のところ、文字列キャストを使用して負のインデックスを設定すると、問題を回避できます。a.fooa['foo']

a['' + (i =-1)] = p

結論:ブラウザのバグ

于 2012-05-17T02:36:48.227 に答える
2

これは私にはJavaScriptCoreのバグのように聞こえます。おそらくfoo、2回目に呼び出され、JITtedコードがバグを導入したときにJITtedされています。

JavaScriptCoreに対してバグを報告し、テストケースを添付することをお勧めします。

于 2012-05-17T02:39:53.403 に答える