запутался в объявлении функции в {}

18

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

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

Я видел код выше, функция объявлена ​​в {}. Я думаю, что это напечатало бы 0 0, но это печатает 0 5

Маркус Ли
источник
Отвечает ли это на ваш вопрос? Какова точная семантика функций уровня блока в ES6?
Джонас
1
В строгом режиме это логи 0 undefined.
CertainPerformance
@ surePerformance хорошо, это объяснимо, но я не могу объяснить, что a = 5оставляет блок. По словам Берги в дупе, function aбудут подняты.
Джонас
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¹);

На самом деле это не является частью спецификации, это является частью семантики совместимости с устаревшим веб-интерфейсом , поэтому не объявляйте функции внутри блоков и не полагайтесь на этот код, который будет вести себя таким образом .

Это также объясняется здесь

Джонас Уилмс
источник
Но почему при достижении объявления функции блочная переменная будет скопирована во внешнюю переменную?
Чор
@ Кор, нет, в спецификации так сказано. Понятия не имею почему.
Джонас