Введение в подъем в JavaScript

Когда вы учились программировать на JavaScript, преподаватели, наставники или случайные люди на StackOverflow говорили вам, что вы хотите избежать проблем с подъемом в коде, используя const или let.

Но вы спрашиваете себя, что это за чертовщина — hoisting, и почему я должен избегать его? Ну, это как раз то, что нужно!

Hoisting — это когда движок JavaScript перемещает объявления переменных и функций в верхнюю часть их соответствующей области видимости перед выполнением кода.

Пример объявления переменной Hoisting:

x = 6
var x;
console.log(x) 
// x would be equal to 6 with no errors thrown
Вход в полноэкранный режим Выход из полноэкранного режима

Естественно, вы подумаете, что этот код не будет работать, потому что вы не можете присвоить переменную и затем разместить объявление под ней, верно?

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

Пример поднятия в объявлении функции:

dogBreed('Miniature Schnauzer')

function dogBreed(name) {
  console.log('My favorite dog breed is the ' + name + '!') 
}
// My favorite dog breed is the Miniature Schnauzer!
Вход в полноэкранный режим Выход из полноэкранного режима

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

Смешивание этих двух понятий может привести к очень запутанному коду. Возьмем, к примеру, этот фрагмент кода:

var dogBreed = "Pug";
var favDogBreed = function () {
  console.log("My favorite dog breed: " + dogBreed);
    var dogBreed = "Shih Tzu";
      console.log("Bob's favorite dog breed: " + dogBreed);
};

favDogBreed();
// Original favorite dog: undefined
// New favorite dog: Shih Tzu 
Вход в полноэкранный режим Выход из полноэкранного режима

Как ни странно, JavaScript инициализировал первую переменную dogBreed значением undefined, потому что она была поднята, а затем начал выполнять функцию, поэтому мы и получили такой результат.

Переменные, которые инициализируются в JavaScript, однако, не поднимаются. Интересно, что в приведенном ниже фрагменте кода выводится NaN:

console.log(x + y)
var x = 4
var y = 2
// Output is NaN
Вход в полноэкранный режим Выход из полноэкранного режима

Это происходит потому, что JavaScript поднимает x и y, но не их соответствующие инициализации = 4 и = 2, что приводит к NaN, потому что x и y не являются числами!

К счастью, в 2015 году появилась новая версия JavaScript ES6, в которой были введены let и const, которые фактически устарели var.

Рассмотрим еще раз favDogBreed, но объявим все с помощью let вместо var:

let dogBreed = "Pug";
let favDogBreed = function () {
  console.log("My favorite dog breed: " + dogBreed);
    let dogBreed = "Shih Tzu";
      console.log("Bob's favorite dog breed: " + dogBreed);
};

favDogBreed();
// This will throw a ReferenceError and not let this code run
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь все в порядке в мире, и инженеру придется пойти и исправить свой запутанный код.

Однако то, что ошибки теперь не возникают, не означает, что hoisting вычеркнут из Javascript. Он по-прежнему возникает с переменными, объявленными с помощью let и const, но они никогда не инициализируются. Возьмем, к примеру, этот фрагмент кода:

dogName = "Sparky";
const dogName
console.log(dogName)
// This code doesn't run

dogName = "Sparky";
let dogName
console.log(dogName)
// This results in a ReferenceError
Войти в полноэкранный режим Выйти из полноэкранного режима

Что это значит? Для начала, подъем все еще происходит с этими переменными, объявленными с помощью let и const, но есть некоторые различия.

const отказывается выполняться из-за синтаксической ошибки. То же самое происходит с let, но JavaScript видит переменную и знает о ней, но JavaScript не может использовать переменную, пока она не будет правильно объявлена.

При объявлении с помощью let, наша переменная dogName находится в явлении, называемом временной мертвой зоной, которое да, было бы самым тошнотворным названием для группы, но это то, в чем находится переменная, объявленная с помощью let или const, пока JavaScript не достигнет и не выполнит строку, в которой объявлена переменная.

Временная мертвая зона не применяется к var, потому что JavaScript инициализирует переменную в неопределенное значение, когда к ней обращаются до объявления.

Лучшая практика для предотвращения проблем с подъемом заключается в следующем:

  • Объявлять переменные и функции let и const везде, где это возможно.

  • Всегда объявляйте переменные в начале каждой области видимости, потому что именно так JavaScript и разработчики читают код.

  • Никогда не используйте var.

Поздравляем! Теперь у вас есть лучшее представление о hoisting и о том, как он работает в JavaScript ES6. Эта (часто упускаемая из виду) концепция сбивает с толку разработчиков, как новичков, так и ветеранов, и у вас есть преимущество в понимании и предотвращении ошибок, связанных с hoisting в JavaScript!

Вот некоторые дополнительные ресурсы по этой теме:
W3Schools
MDN
JavaScript Docs

Оцените статью
Procodings.ru
Добавить комментарий