Важно понимать, как подъем может повлиять на прицел. Подъем состоит из двух частей, которые влияют на определение области видимости объявлений: подъем переменной и подъем функции. Начиная с объявления переменных, важно отметить, что с ES6 и введением let
и const
подъем переменных также имел новое уникальное поведение. При использовании var
для объявления ваших переменных механизм JavaScript обрабатывает все объявления так, как если бы они находились в глобальной области, независимо от того, где они были фактически объявлены. По сути, это поднимает переменную на верхний уровень. Важно отметить, что это меняется, когда мы начинаем использовать var
в функциональных блоках, но мы рассмотрим это в следующих разделах, касающихся подъема функций. Это означает, что переменная фактически доступна до того, как она будет объявлена. Давайте посмотрим на пример:
Обратите внимание, что первый console.log(salary);
не выдает ошибок и возвращает undefined
. Это означает, что движок JavaScript обнаружил var salary
, объявленный ниже, но во время этого первого console.log еще не имел значения этой переменной. Его подняли наверх. Такое мощное поведение может привести к ошибкам в нашем коде, если мы не будем осторожны при объявлении переменных.
Если мы используем let
или const
вместо var
в этом примере, консоль вернет ошибку и прекратит все дальнейшее выполнение. Если вы используете babel, поведение для let
или const
в этом примере по существу одинаковое - движок JavaScript видит объявление, но не знает значение, возвращающее undefined
для первого console.log
. Важно помнить, что const
объявления не могут быть переназначены и должны быть объявлены во время их инициализации. Также важно помнить, что мы должны максимально полагаться на объявление переменной ES6 с let
или const
! ES5 var
по-прежнему работает, но рекомендуется использовать let
для переменных, которые будут изменяться, и const
для постоянных переменных. Поскольку мы не работаем с данными и не включаем объявление как часть функции, все три var
, let
и const
будут вести себя одинаково. Все становится немного сложнее, когда мы добавляем функции в микс.
Область видимости уровня блока
Область видимости на уровне блоков помогает обеспечить больший контроль над жизненным циклом переменной. Объявления уровня блока были введены в ES6 и делаются внутри блока {}
. Мы собираемся продемонстрировать объявления на уровне блоков с использованием let
и const
, чтобы увидеть, как это влияет на доступность переменной.
пусть декларации
Синтаксис let
очень похож на var
. Однако вы хотите разместить свои let
объявления вверху блока, чтобы они были доступны в этом блоке. Давайте посмотрим на пример, в котором if
используется для оценки условия.
Это вызывает ошибку, потому что в первом console.log
в строке 2 механизм Javascript не видит salary
определенных и не видит объявлений let
в блоках if/else
. Ошибка не позволяет нам вызвать функцию в строке 13- getRaise(yearsEmployed = 6);
. Если мы просто закомментируем этот console.log, наша функция сработает и выведет прогнозируемый результат на консоль.
Мы не можем использовать const
в этом примере, потому что значение переменной salary
изменяется с условием yearsEmployed.
. Использование const
для любого salary
в этом примере вызовет ошибку.
Функция подъема
Подъем переменной - это не то же самое, что подъем функции - он уникален сам по себе. Помните, что есть 2 способа создания функций - Объявление функции и Выражение функции.
В Javascript объявления функций поднимают определения функций. Это означает, что эти функции можно использовать даже до их объявления. Синтаксис объявления функции прост, console.log
интерпретируется и выводится на консоль, даже если функция вызывается до определения функции:
Выражение функции относится к функции, определенной в выражении. Выражение функции может быть анонимным, поэтому мы можем использовать синтаксис стрелочной функции в функциональных выражениях. Однако они не поднимаются и не могут использоваться до тех пор, пока не будут определены.
Авария
Давайте разберемся с этим на другом примере. Мы собираемся использовать тот же пример последовательности переключения выполнения, объявления переменных или объявлений функций, чтобы увидеть, как все это может повлиять на подъем. В нашем первом примере мы будем использовать var
для наших объявлений переменных, а также для выражения функции.
Интересно, правда? В этом примере у нас есть var salary
в глобальной области видимости, но внутри функции при первом вызове она не определена. Что дает? Что ж, из-за того, как движок JavaScript запускает код, который ищет salary
в функциональном блоке. Поскольку в блоке есть var salary
, он распознает, что он присутствует с первым console.log
, но еще не знает его значения. var salary =’$1000';
находится в глобальной области видимости, а console.log
в блоке его не ищут. Посмотрите, как это меняет результат, просто удаляя объявление var
внутри блока:
Сумасшедший, правда? Теперь он знает, что мы корректируем значение var
в глобальной области видимости при выполнении блока. Он показывает значение первого salary
и изменяет значение. Тот же результат будет при перемещении первого var salary
внутрь блока.
Теперь это тоже выражение функции - мы назначаем var hoisting
определение функции. Помните: мы не можем выполнить выражение функции до его определения:
Если мы изменим его на объявление функции…
Оно работает!
Итак, теперь давайте вернем пример к исходному формату, но заменим var
s новыми, фантастическими объявлениями переменных let
или const
. Если мы изменим это первое var salary
на const salary
, мы не сможем перезаписать значение в нашем блоке, верно?
Неправильный! Он по-прежнему ведет себя так же, как и в нашем первом примере, потому что const salary
находится в глобальной области. Блок распознает, что в нем есть переменная salary
, и игнорирует глобальную переменную salary
. Если бы мы использовали let
в том же контексте, это дало бы тот же результат. Если мы поместим его в наш блок, мы получим ожидаемое поведение - он выдает ошибку, когда мы пытаемся перезаписать значение:
Теперь, если мы попытаемся использовать let
внутри блока, как вы думаете, что произойдет? Вы могли ожидать, что у него будет такое же поведение - возврат undefined
при первом вызове и регистрация ’$5000’
как часть второго console.log
, верно?
Удивительно - нет! Он не распознает объявление переменной в блоке, если вы используете let
, и выдаст ошибку, останавливающую дальнейшее выполнение. То же самое, если вы переключите этот let
в 7-й строке на const
. Если вы используете let
или const
в блоке, единственный способ, которым это будет работать, - это если он будет объявлен в верхней строке внутри блока и опустить ключевое слово при попытке перезаписать значение:
Довольно аккуратно, да? Небольшие различия в том, как мы делаем объявления - в обеих функциях И переменные могут иметь большое значение в том, как JavaScript читает наш код. С точки зрения подъема, две практики должны поддерживать ваш код в хорошей форме - используйте let
(для переменных, которые будут изменены или переназначены) или const
(для переменных, которые останутся такими же) и всегда объявляйте свои переменные в верхней части функции.