Подъем в JavaScript относится к перемещению объявления функций и переменных в верхнюю часть их области видимости перед выполнением кода. Объявления переменных и функций переносятся интерпретатором вверху.
Подъем позволяет безопасно использовать функции в программе JavaScript еще до того, как они будут объявлены. Поднятие переменных и функций также может привести к непредвиденным ошибкам и обычно не рекомендуется.
Переменный подъем
Давайте разберемся с подъемом переменных на примере:
1. console.log(variableHoistingExample); // undefined 2. var variableHoistingExample = 'Variable Hoisted';
В строке 1 будет напечатано значение variableHoistingExample
undefined
поскольку интерпретатор JavaScript переместит объявление variableHoistingExample
перед строкой 1. Когда переменная объявляется с использованием var
, эта переменная автоматически инициализируется значением по умолчанию undefined. Приведенный выше код будет выглядеть примерно так, как показано ниже, после того как интерпретатор переместит объявление в начало области видимости переменной:
1. var variableHoistingExample; 2. console.log(variableHoistingExample); // undefined 3. variableHoistingExample = 'Variable Hoisted';
Хотя переменная может быть объявлена с использованием var
, let
и const
.
вар подъемный
При использовании var
переменные автоматически инициализируются с помощью undefined
.
1. console.log(example) 2. var example = 'Print Example'
В приведенном выше примере, как обсуждалось ранее, переменная example будет объявлена в верхней области видимости и будет инициализирована значением undefined. Хотя даже для того, чтобы получить undefined, мы должны объявить переменную. Если переменная не объявлена, мы получим ReferenceError
о том, что интерпретатор не может найти объявление этой переменной.
1. console.log(example) // Uncaught ReferenceError: Cannot access 'example' before initialization
2. example = 'Example for ReferenceError';
Как и в приведенном выше примере, переменная example
не объявлена, поэтому мы получаем ReferenceError в строке 1. Мы также можем разделить объявление и инициализацию самостоятельно, а не интерпретатор.
var example console.log(example) //undefined example = 'Example' console.log(example) //Example
В более крупных проектах обычно следует избегать использования var
, так как это может вызвать различные проблемы, такие как инициализация переменной с помощью undefined
или даже присвоение ReferenceError
. К счастью, let
и const
представили ECMAScript 2015, который ведет себя по-другому.
пусть и const подъем
Переменные, которые объявлены с использованием let
и const
, также поднимаются в верхнюю часть своей области видимости, хотя переменные не инициализируются. В отличие от var
, доступ к переменной, объявленной с помощью let и const, всегда будет возвращаться с ReferenceError
.
1. console.log(example); // Uncaught ReferenceError: Cannot access 'example' before initialization
2. let example = 'Example'; 3. console.log(constExample); // Uncaught ReferenceError: Cannot access 'constExample' before initialization
4. const constExample = 'Const Example';
Причина ReferenceError
при объявлении переменных с помощью let и const связана с Temporal Dead Zone(TDZ)
.
Временная мертвая зона
TDZ — это зона, в которой переменные временно мертвы и не имеют назначенных значений. TDZ начинается с начала области, охватывающей переменную, и заканчивается, когда переменная объявляется.
{ // start of example TDZ console.log(example) // Reference Error console.log('Above line will give error') const example = 'Example' // End of TDZ }
Доступ к любой переменной в TDZ всегда будет приводить к ReferenceError
, а доступ к любой переменной после объявления и до инициализации (в случае let) приведет к неопределенности.
Функциональный подъем
Объявления функций также поднимаются наверх своей области. Функции поднимаются для безопасного вызова до того, как они будут объявлены. Основное преимущество заключается в том, что он скрывает реализацию конкретной функции, которую можно объявить внизу файла. Пользователь может сосредоточиться только на том, что делает код, а не на реализации.
funcExample() // Function hoisting example function funcExample() { console.log('Function hoisting example') }
При подъеме функций поднимаются только объявления функций, а не выражения функций. Использование стрелочных функций может привести либо к TypeError
, либо к ReferenceError
в зависимости от области видимости переменной.
1. varFunctionExample() //Uncaught TypeError:
varFunctionExampleis not a function 2. var
varFunctionExample = () => { console.log('Var Function Example') } 3. letFunctionExample()// Uncaught ReferenceError: Cannot access '
letFunctionExample' before initialization 4. let
letFunctionExample = () => { console.log('Let Function Example') } 5. constFunctionExample()// Uncaught ReferenceError: Cannot access '
constFunctionExample' before initialization 6. let
constFunctionExample = () => { console.log('Const Function Example') }
Также использование функций перед объявлением является вопросом личных предпочтений. Согласно руководству Airbnb, мы всегда должны использовать названные функции и избегать поднятия функций.
Заключение
Мы поняли, что такое подъем и различные типы подъемов, которые являются переменным подъемом и подъемом функций. В подъеме переменных мы поняли о подъеме var
, let
и const
.