Про Hoisting переменных - часть 1 основы
На
последнем стриме с @artalar выяснилось, что на старости лет я подзабыл как именно работает hoisting переменных в JavaScript.
Hoisting, вкратце, - это возможность использовать функции, классы и переменные (объявленные через var) до их декларации (на самом деле - не совсем, смотрите вторую часть) - получается они поднимаются (hoist) вверх. Хотя на русский hoisting часто переводят как “всплытие”.
В деталях я объяснять не буду, достаточно глянуть
какой-нибудь MDN (или в статье от
Dmitry Soshnikov).
Увы, так случилось, что в checklist классического JavaScript собеседования, вместе с замыканиями и контекстами, просочился и hoisting переменных (например вот
про это спрашивают ребята из отсобеседования).
Сама по себе, возможность использования переменных до объявления,
это просто артефакт, доставшийся им от функций . В нем не было никакой нужды или пользы, и позже в let и const эту возможность убрали.
Все что надо знать про hoisting с практической точки зрения: 1. Функции и классы можно использовать до объявления
2. Все переменные надо объявлять до использования (а еще лучше в начале функции)
Про Hoisting переменных - часть 2 (скучная)Забавно, но в
спеке слово
hoisting
встречается ровно два раза, причем его нет в непосредственном описании поведения, которое мы обсуждаем.
Глянем про
var.
A var statement declares variables that are scoped to the running execution context’s VariableEnvironment. Var variables are
created when their containing Lexical Environment is instantiated and
are initialized to undefined when created.
Теперь глянем в
let/constlet and const declarations define variables that are scoped to the running execution context’s LexicalEnvironment.
The variables are
created when their containing Lexical Environment is instantiated
but may not be accessed in any way until the variable’s LexicalBinding is evaluated.
Забавно, что непосредственно “всплывательная” часть - попадание в лексическую среду на этапе инициализации есть и у let/const, но там добавляется отдельная проверка, чтобы не позволить использовать переменные раньше времени.