mylony co do deklaracji funkcji w {}

18

var a;
if (true) {
  a = 5;

  function a() {}
  a = 0;
  console.log(a)
}
console.log(a)

Widziałem powyższy kod, funkcja jest zadeklarowana w {}. Myślę, że wypisze 0 0, ale wypisze 0 5

Marcus Lee
źródło
Czy to odpowiada na twoje pytanie? Jaka jest dokładna semantyka funkcji na poziomie bloku w ES6?
Jonas Wilms
1
W trybie ścisłym loguje się 0 undefined.
CertainPerformance
@certainPerformance dobrze, to można wytłumaczyć, ale nie wyjaśniam, że a = 5opuszcza blok. Według bergi w dupe, function azostanie podniesiony.
Jonas Wilms
2
Wydaje się, że zmienna bloku o lokalnym zasięgu zostaje skopiowana do bloku zewnętrznego po osiągnięciu deklaracji funkcji.
Jonas Wilms

Odpowiedzi:

13

Zdarza się:

(1) Istnieją dwie deklaracje zmiennych a, jedna wewnątrz bloku, a druga poza nim.

(2) Deklaracja funkcji zostaje podniesiona i powiązana ze zmienną bloków wewnętrznych.

(3) a = 5zostaje osiągnięty, co zastępuje zmienną blokową.

(4) deklaracja funkcji została osiągnięta, a zmienna blokowa jest kopiowana do zmiennej zewnętrznej. Obaj mają teraz 5 lat.

(5) a = 0został osiągnięty, co zastępuje zmienną blokową. Nie ma to wpływu na zmienną zewnętrzną.

 var a¹;
 if (true) {
   function a²() {} // hoisted
   a² = 5;
   a¹ = a²; // at the location of the declaration, the variable leaves the block      
   a² = 0;
  console.log(a²)
}
console.log(a¹);

To tak naprawdę nie jest częścią specyfikacji, jest częścią semantyki zgodności ze starszymi wersjami sieci , więc nie deklaruj funkcji w blokach i nie polegaj na tym kodzie, aby zachowywał się w ten sposób .

Wyjaśniono to również tutaj

Jonas Wilms
źródło
Ale dlaczego po osiągnięciu deklaracji funkcji zmienna blokowa zostanie skopiowana do zmiennej zewnętrznej? Wniosek, że z debuggera?
Chor
@Chor nie, specyfikacja tak mówi. Nie mam pojęcia dlaczego.
Jonas Wilms