2016-03-09 26 views
6

Quando eseguo la seguente pagina HTML di prova in Chrome, vedo quanto segue nella console di debug:genitoreNode perso nella chiusura interna di Javascript? Bug di Chrome?

Has parent? true 
Has parent? false 

ho ragione nel ritenere che questo un bug Chrome (non accade in altri browser), o è Chrome nel suo diritto di farlo per qualche motivo? Il risultato è stato un bug in una delle mie app Web e alla fine ho isolato questo snippet per riprodurre il problema principale.

Ecco la pagina di prova:

<!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: Avrei detto che sto testando su Windows 7 con Chrome 49.0.2623.87 m (64-bit). È stato anche in grado di repro su OSX 10.11.2 con Chrome 49.

Inoltre, devo dire che a volte si mostra vero/vero e talvolta vero/falso. Potrebbe essere necessario ricaricare la pagina alcune volte per assistere al problema. Non sono sicuro, ma è possibile che anche gli strumenti di debug (console) siano aperti.

Grazie mille.

+0

funziona per me in Chrome 48 OSX – elclanrs

+0

non riesco a riprodurre (Chrome 48.0.2564.109). Sei sicuro che il 'testParentEl' non è mutato tra le chiamate? – Bergi

+0

Avrei detto che sto testando su Windows 7 con Chrome 49.0.2623.87 m (64-bit). Inoltre, vorrei ricordare che a volte si mostra vero/vero e talvolta vero/falso. Potrebbe essere necessario ricaricare la pagina alcune volte per assistere al problema. Non sono sicuro, ma è possibile che anche gli strumenti di debug (console) siano aperti. – logidelic

risposta

0

credo che questo è stato finalmente risolto da Chrome v50 (o almeno non sono stato in grado di ripro dall'aggiornamento).

0

La mia ipotesi è che testChildEl.parentNode non faccia riferimento allo fortemente, quindi è raccolta dei dati inutili.

Sia riferimento testParentEl dentro il timeout e l'aggiunta di un riferimento forte per testParentEl sul testChildEl risolve il problema per me:

(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

Questo suona davvero come un insetto per me. – Bergi

+0

Ci sono già dei riferimenti "forti" e "deboli" in Javascript? La mia comprensione era che non ci sono. Anch'io ho scoperto che il problema poteva essere risolto avendo un riferimento esplicito a testPartEl dalla chiusura. Sì, sono convinto che sia un bug. Chiaramente alcune ottimizzazioni di Chrome sono andate male. Non sono sicuro del motivo per cui nessun altro sembra essere un po 'troppo vicino. – logidelic

+0

@logidelic ES6 introduce WeakSets e WeakMaps, che memorizzano riferimenti deboli agli oggetti. Oltre a questo è tutto dipendente dall'implementazione, la specifica non richiede un garbage collector. Bu definizione, non dovrebbe essere possibile rilevare se un oggetto è stato garbage collector, quindi questo è un bug. – Oriol