Dlaczego wartość typeof null zmienia się wewnątrz pętli?

Wykonanie tego fragmentu w konsoli Chrome:

function foo() {
    return typeof null === 'undefined';
}
for(var i = 0; i < 1000; i++) console.log(foo());

Powinien drukować 1000 razy false, ale na niektórych maszynach będzie drukować false przez kilka iteracji, a następnie true przez resztę.

Tutaj wpisz opis obrazka

Dlaczego tak się dzieje? Czy to tylko pluskwa?
 109
Author: Sergey Novikov, 2016-06-21

4 answers

Istnieje błąd chromium otwarty dla tego:

Problem 604033-kompilator JIT nie zachowuje zachowania metody

Więc tak, to tylko pluskwa!

 74
Author: Slumber86,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-21 12:39:46

To właściwie błąd V8 JavaScript engine (Wiki).

Ten silnik jest używany w Chromium, Maxthron, Android OS, Node.js itp.

Stosunkowo prosty opis błędu znajdziesz w tym temacie :

Nowoczesne silniki JavaScript kompilują kod JS do zoptymalizowanego kodu maszynowego kiedy jest wykonywany (Just In Time compilation), aby działał szybciej. Jednak etap optymalizacji ma pewien początkowy koszt wydajności w Giełda na dłuższą metę, więc silnik dynamicznie decyduje czy metoda jest tego warta w zależności od tego, jak często jest używana.

W tym przypadku pojawia się błąd tylko w zoptymalizowanej ścieżce, podczas gdy nieoptymalizowana ścieżka działa dobrze. Tak więc na początku metoda działa jak zamierzony, ale jeśli jest wywoływany w pętli wystarczająco często w pewnym momencie silnik zdecyduje się na jego optymalizację i zastąpi go buggy wersja.

Ten błąd został naprawiony w V8 (commit), podobnie jak w Chromium (bug report) i NodeJS (commit).

 37
Author: Sergey Novikov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-22 07:55:37

Aby odpowiedzieć na bezpośrednie pytanie, dlaczego się zmienia, błąd znajduje się w procedurze optymalizacji" JIT " silnika V8 js używanego przez Chrome. Na początku kod jest uruchamiany dokładnie tak, jak został napisany, ale im więcej go uruchamiasz, tym większy potencjał korzyści z optymalizacji przewyższają koszty analizy.

W tym przypadku, po wielokrotnym wykonaniu w pętli, kompilator JIT analizuje funkcję i zastępuje ją zoptymalizowaną wersją. Niestety, analiza sprawia, że nieprawidłowe założenie, a zoptymalizowana wersja nie daje w rzeczywistości poprawnego wyniku.

Konkretnie, użytkownik RainHappens sugeruje , że jest to błąd w typ propagacji :

Wykonuje również pewne propagacje typu(jak w jakich typach może być zmienna etc). Istnieje specjalny typ "niewykrywalny", gdy zmienna jest niezdefiniowana lub null. W tym przypadku optimizer idzie "null jest niewykrywalne, więc można go zastąpić ciągiem "undefined" dla porównanie.

Jest to jeden z trudniejszych problemów z optymalizacją kodu: Jak zagwarantować, że kod, który został przestawiony pod kątem wydajności, nadal będzie miał taki sam efekt jak oryginał.

 18
Author: IMSoP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-21 15:37:09
 1
Author: user835611,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-29 03:41:36