плутати декларацію про функцію в {}


18

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

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

Я бачив код вище, функція оголошена в {}. Я думаю, що він надрукував би 0 0, але він надрукував 0 5


Чи відповідає це на ваше запитання? Яка точна семантика функцій рівня блоку в ES6?
Jonas Wilms

1
У суворому режимі він реєструється 0 undefined.
Окреме виконання

@certainPerformance добре, це зрозуміло, але я не можу пояснити, що a = 5залишає блок. За словами Бергі в дупі, function aбудуть підніматися.
Jonas Wilms

2
Здається, що мінлива блоку локалізованої області скопіюється у зовнішній блок при досягненні декларації функції.
Йонас

Відповіді:


13

Буває таке:

(1) Існують дві мінливі декларації a, одна всередині блоку та одна поза нею.

(2) Оголошення функції отримує підйом і прив’язується до змінної внутрішніх блоків.

(3) a = 5досягнуто, що перекриває блокову змінну.

(4) досягається оголошення функції, а змінна блоку копіюється у зовнішню змінну. Обоє зараз 5.

(5) a = 0досягнуто, що перекриває блокову змінну. На зовнішню змінну це не впливає.

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

Це насправді не є частиною специфікації, вона є частиною семантики сумісності веб-застарілих даних , тому не оголошуйте функції всередині блоків і не покладайтеся на цей код, щоб він поводився таким чином .

Це також пояснено тут


Але чому після досягнення декларації функції блок змінна буде скопійована у зовнішню змінну? Висновок, що з налагоджувача?
Чор

@Chor ні, специфікація так говорить. Я поняття не маю, чому.
Йонас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.