2016-03-09 12 views
6

Kiedy wykonać poniższą testową stronę HTML w Chrome, widzę następujące w konsoli debugowania:ParentNode jest zagubiony na wewnętrznym zamknięciu Javascript? Błąd Chrome?

Has parent? true 
Has parent? false 

mam rację zakładając, że to błąd Chrome (to nie zdarza się w innych przeglądarkach) lub czy Chrome ma do tego prawo z jakiegoś powodu? To spowodowało błąd w jednej z moich aplikacji internetowych i w końcu wyizolowałem ten fragment, aby naprawić główny problem.

Oto strona testowa:

<!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: Powinienem wspomnieć, że jestem testowania Windows 7 z Chrome 49.0.2623.87 m (64-bit). Był również w stanie repro na OSX 10.11.2 z Chrome 49.

Należy również wspomnieć, że czasami wyświetla true/true, a czasem true/false. Być może będziesz musiał przeładować stronę kilka razy, aby być świadkiem problemu. Nie jestem pewien, ale możliwe, że narzędzia do debugowania (konsola) również muszą być otwarte.

Wielkie dzięki.

+0

Działa dla mnie w Chrome 48 OSX – elclanrs

+0

Nie mogę odtworzyć (Chrome 48.0.2564.109). Czy jesteś pewien, że 'testParentEl' nie jest zmutowany między połączeniami? – Bergi

+0

Powinienem wspomnieć, że testuję na Windows 7 z Chrome 49.0.2623.87 m (64-bit). Należy również wspomnieć, że czasami wyświetla on wartość true/true, a czasem true/false. Być może będziesz musiał przeładować stronę kilka razy, aby być świadkiem problemu. Nie jestem pewien, ale możliwe, że narzędzia do debugowania (konsola) również muszą być otwarte. – logidelic

Odpowiedz

0

wierzę to zostało ostatecznie naprawione przez Chrome v50 (lub przynajmniej nie byłem w stanie repro od aktualizacji).

0

Domyślam się, że testChildEl.parentNode nie zawiera silnego odniesienia do testParentEl, więc zbiera śmieci.

Zarówno przedstawieniu testParentEl wewnątrz limitu czasu i dodanie silne odniesienie do testParentEl na testChildEl rozwiązać problem dla mnie:

(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

To naprawdę brzmi jak błąd dla mnie. – Bergi

+0

Czy w JavaScript istnieje już coś takiego jak "silne" i "słabe" odniesienia? Moje zrozumienie było takie, że nie ma. Ja również odkryłem, że problem można naprawić poprzez wyraźne odwołanie się do testPartEl z poziomu zamknięcia. Tak, jestem przekonany, że to błąd. Najwyraźniej część optymalizacji Chrome poszła źle. Po prostu nie jestem pewien, dlaczego nikt nie wydaje się być przez to trochę. – logidelic

+0

@logidelic ES6 wprowadza WeakSets i WeakMaps, które przechowują słabe odniesienia do obiektów. Poza tym wszystko zależy od implementacji, specyfikacja nie wymaga odśmiecania. Definicja Bu, nie powinno być możliwe wykrycie, czy obiekt został zbieraczem śmieci, więc jest to błąd. – Oriol

Powiązane problemy