2016-03-09 14 views
6

私はChromeで以下の試験HTMLページを実行すると、私はデバッグコンソールで以下を参照してください。parentNodeがJavascriptの内部クロージャで失われていますか? Chromeのバグ?

Has parent? true 
Has parent? false 

私は、(それは他のブラウザでは発生しません)右このクロームのバグと仮定してアムまたは何らかの理由でこれを行う権利がChrome内にありますか?それは私のWebアプリケーションの1つにバグをもたらし、最終的にこのスニペットを分離してコアの問題を再現しました。

<!DOCTYPE HTML> 
 
<html> 
 
    <head> 
 
    <meta charset="UTF-8"> 
 
    <title></title> 
 
    </head> 
 
    <body class=""> 
 
     
 
     
 
     <script> 
 
     function testDoodle() { 
 
      var testParentEl = document.createElement('div'); 
 
      var testChildEl = testParentEl.appendChild(document.createElement('div')); 
 
      
 
      document.body.innerHTML+=('Has parent? ' + !!testChildEl.parentNode+'<br>'); 
 
      console.log('Has parent? ' + !!testChildEl.parentNode); 
 
      
 
      setTimeout(function() { 
 
       document.body.innerHTML+=('Has parent? ' + !!testChildEl.parentNode+'<br>'); 
 
       console.log('Has parent? ' + !!testChildEl.parentNode); 
 
      }, 
 
      2000); 
 
      return; 
 
     } 
 
     testDoodle(); 
 
     </script> 
 

 
    </body> 
 
</html>

EDIT:ここ

は、テストページで私はクローム49.0.2623.87メートル(64ビット)でWindows 7上でテストしてることに言及している必要があります。また、Chrome 49でOSX 10.11.2を再現することができました。

また、時にはtrue/trueとtrue/falseを表示することがあります。問題を目で確認するには、ページを数回リロードする必要があります。私には分かりませんが、デバッグツール(コンソール)も開いている必要があります。

ありがとうございました。

+0

Chromeで動作する48 OSX – elclanrs

+0

再現できません(Chrome 48.0.2564.109)。 'testParentEl'が呼び出し間で突然変異していないことを確かめますか? – Bergi

+0

私は、Windows 7でChrome 49.0.2623.87 m(64ビット)を使用してテストしていることを述べておきます。 また、true/trueとtrue/falseを表示することがあります。問題を目で確認するには、ページを数回リロードする必要があります。私には分かりませんが、デバッグツール(コンソール)も開いている必要があります。 – logidelic

答えて

0

私は信じていますこれは最終的にChrome v50によって修正された(または少なくとも私は更新以来reproできなかった)。

0

私の推測では、testChildEl.parentNodetestParentElを強く参照していないので、ガベージコレクションされています。

どちらのタイムアウト内testParentElを参照してtestChildEltestParentElへの強い参照を追加する私のための問題を修正:

(function testDoodle() { 
 
    var testParentEl = document.createElement('div'); 
 
    var testChildEl = testParentEl.appendChild(document.createElement('div')); 
 
    setTimeout(function() { 
 
    testParentEl; // Prevents it from being garbage collected 
 
    document.write('Has parent? ' + !!testChildEl.parentNode); 
 
    }, 100); 
 
})();

(function testDoodle() { 
 
    var testParentEl = document.createElement('div'); 
 
    var testChildEl = testParentEl.appendChild(document.createElement('div')); 
 
    testChildEl.strongParent = testParentEl; // Prevents garbage collection 
 
    setTimeout(function() { 
 
    document.write('Has parent? ' + !!testChildEl.parentNode); 
 
    }, 100); 
 
})();

+1

これは本当に私のバグのように聞こえる。 – Bergi

+0

Javascriptに "strong"と "weak"という参照がすでにありますか?私の理解はそこにないということでした。私は、クロージャ内からtestPartElへの明示的な参照を持つことで問題を解決できることも発見しました。 はい、私はそれがバグだと確信しています。明らかにChromeの最適化がうまくいかないなぜ他の人がそれに少し似ているように見えるのか分かりません。 – logidelic

+0

@logidelic ES6は弱い参照をオブジェクトに格納するWeakSetとWeakMapsを導入しています。これとは別に、実装に依存していますが、仕様にはガベージコレクタは必要ありません。 Bu定義では、オブジェクトがガベージコレクタであったかどうかを検出することはできないはずです。したがって、これはバグです。 – Oriol

関連する問題