bingung tentang deklarasi fungsi di {}

18

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

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

Saya melihat kode di atas, fungsi dideklarasikan dalam {}. Saya pikir itu akan mencetak 0 0, tetapi mencetak 0 5

Marcus Lee
sumber
Apakah ini menjawab pertanyaan Anda? Apa semantik yang tepat dari fungsi level blok di ES6?
Jonas Wilms
1
Dalam mode ketat, log 0 undefined.
Kinerja Tertentu
@certainPerformance dengan baik, itu bisa dijelaskan, tapi saya gagal menjelaskan yang a = 5meninggalkan blok. Menurut bergi dalam penipuan itu, function aakan diangkat.
Jonas Wilms
2
Tampaknya seolah-olah variabel blok yang dicakup secara lokal akan disalin ke blok luar ketika mencapai deklarasi fungsi.
Jonas Wilms

Jawaban:

13

Berikut ini terjadi:

(1) Ada dua deklarasi variabel a, satu di dalam blok dan satu di luarnya.

(2) Deklarasi fungsi diangkat, dan terikat ke variabel blok dalam.

(3) a = 5tercapai, yang menimpa variabel blok.

(4) deklarasi fungsi tercapai, dan variabel blok disalin ke variabel luar. Keduanya 5 sekarang.

(5) a = 0 tercapai, yang menimpa variabel blok. Variabel luar tidak terpengaruh oleh ini.

 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¹);

Ini sebenarnya bukan bagian dari spesifikasi, ini adalah bagian dari semantik kompatibilitas web warisan , jadi jangan mendeklarasikan fungsi di dalam blok dan tidak bergantung pada kode ini untuk berperilaku dengan cara ini .

Ini juga dijelaskan di sini

Jonas Wilms
sumber
Tetapi mengapa setelah deklarasi fungsi tercapai, variabel blok akan disalin ke variabel luar? Disimpulkan dari debugger?
Chor
@ Tidak, spec mengatakan begitu. Saya tidak tahu kenapa.
Jonas Wilms