Происходит следующее:
(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¹);
На самом деле это не является частью спецификации, это является частью семантики совместимости с устаревшим веб-интерфейсом , поэтому не объявляйте функции внутри блоков и не полагайтесь на этот код, который будет вести себя таким образом .
Это также объясняется здесь