Подъем в 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: varFunctionExample is 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 .