Это одно из тех слов, которые кажутся трудными, но на самом деле легко укладываются в голове.

Поднятие означает резервирование места в куче памяти для ваших переменных и функций. переменные, определенные с помощью ключевого слова var, "частично" поднимаются, а объявления функций "полностью" поднимаются.

Возьмите приведенный ниже код, например:

console.log(spell)
fireball()
var spell = 'freeze'
function fireball() {
  console.log('fireball!')
}
// Result:
undefined
'fireball!'

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

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

function fireball() {
  console.log('fireball!')
}
console.log(spell)
fireball()
...

Хорошо, функции просты, мы просто представляем, что это написано вверху!

Но как насчет переменных, определенных с помощью ключевого слова var? мы могли бы использовать переменную «заклинание», но мы не получаем ее значение, вместо этого мы получаем неопределенное значение. Это потому, что мы не полностью поднимаем переменную, представляем ее как программу, объявляющую ту же переменную вверху, но вместо этого инициализируем ее значением undefined, и когда программа читает наше объявление, она просто меняет значение того, что она объявила, вот так :

var spell = undefined
console.log(spell)
spell = 'freeze'

Хорошо, это имеет смысл! Вот почему мы получаем неопределенность, когда ссылаемся на переменную до ее объявления.