Много было сказано о подъеме в JavaScript, но это все еще остается совершенно неизвестной темой и причиной многих ошибок во многих приложениях Javascript.
Давайте пройдемся по нему, а затем посмотрим, как это работает с var, а затем с let / const.
Прежде чем мы начнем с подъема, давайте рассмотрим, что означает "область действия" в Javascript.
Область действия. Проще говоря, "область действия" - это видимость переменной в JavaScript. Это означает, что он определяет, где в коде можно получить доступ к этой переменной и, следовательно, ее значение может быть прочитано или изменено.
Переменные в JavaScript могут иметь локальную или глобальную область видимости в зависимости от того, где они определены.
Все переменные, определенные (с помощью 'var') в функции, имеют область действия, ограниченную этой функцией, и, как говорят, имеют локальную область действия.
Считается, что все переменные, которые определены вне какой-либо функции (например, непосредственно внутри тега скрипта в HTML), имеют глобальную область действия.
Все переменные, определенные без ключевого слова "var", также становятся частью глобальной области видимости при условии, что мы не запускаем код JavaScript в "строгом режиме".
<script> var globalVariable = "Hello! I'm a global!"; function scoper() {//is that even a word? var localVariable = "I'm inside a function, so I'm limited to local scope." console.log(globalVariable); console.log(localVariable); } scoper(); //Hello! I'm a global! //I'm inside a function, so I'm limited to local scope. console.log(globalVariable); //Hello! I'm a global! console.log(localVariable); //Uncaught ReferenceError: localVariable is not defined </script>
Область действия в let и const:
Scope по-разному работает с let и const, оба из которых были введены как часть спецификации ES6.
И let, и const имеют область действия блока, что просто означает, что их область действия ограничена блоком (и подблоками), оператором или выражением, в котором они используются.
Чтобы понять, что мы подразумеваем под блоком в JavaScript, просто перейдите от оператора let вверх и найдите первую открывающую скобку ({); Оператор let будет ограничен по объему оператором let, а соответствующая закрывающая скобка (}) - открывающей скобкой ({), которую вы нашли. Набор скобок может быть функцией или просто циклом for.
Например,
<script> function myBigFunc(){ if(true){ let blockScopedVariable = 1; } if(true){ var functionScopedVariable = 2; } console.log(blockScopedVariable); //Uncaught ReferenceError: blockScopedVariable is not defined console.log(functionScopedVariable); //2 } </script>
Переменная blockScopedVariable была объявлена с помощью let и, следовательно, доступна для доступа только внутри своего блока, который представляет собой пару фигурных скобок ({}), заключающих ее.
Переменная «functionScopedVariable» была объявлена с «var», что дало ей локальную область видимости. Таким образом, он доступен внутри всего «myBigFunc».
Теперь, когда мы прочитали, что мы подразумеваем под областью действия, а также увидели простой пример, давайте вернемся к нашей исходной теме.
Подъем. Подъем - это присущее JavaScript поведение, заключающееся в перемещении объявлений переменных в верхнюю часть области видимости.
Поначалу это звучит довольно просто, но давайте разберемся немного.
<script> console.log(x); //undefined var x; </script>
JavaScript автоматически перемещает все объявления переменных наверх, поэтому, хотя мы пытались получить доступ к значению переменной «x» до того, как мы фактически написали для нее объявление, это не привело к ошибке. Чудесно! Теперь посмотрим, что происходит, когда мы инициализируем «x».
<script> console.log(x); //undefined var x = 2; </script>
Упомянутое выше поведение является причиной множества ошибок в JavaScript. JavaScript поднимает объявление (var x), но НЕ инициализацию (= 2) переменной.
Приведенный выше код эквивалентен
<script> var x; console.log(x); //undefined x = 2; </script>
Именно так работает подъем в JavaScript. Разработчики могут создавать простые правила, например всегда инициализировать переменные в верхней части области видимости, что может помочь избежать таких проблем, особенно при работе в больших командах.
Другое решение - использовать let или const. И "let", и "const" не поднимаются. Доступ к ним до того, как они были объявлены, просто вызывает ошибку во время выполнения, что помогает избежать ошибок, которые могут возникнуть из-за подъема.
Подъем с помощью функций:
JavaScript позволяет нам писать функции двумя разными способами. Давайте посмотрим, как подъемник работает с ними обоими:
Объявление функции: объявление функции в JavaScript имеет вид:
function [optional functionName] (params) { //function body }
Этот тип функции поднимается так, что ее можно вызывать в любом месте охватывающей области, даже до объявления функции.
Например:
<script> console.log(myAdditionFunc(5, 7); //12 . //other statements . . function myAdditionFunc (num1, num2){ return num1 + num2; } </script>
Выражение функции. Выражение функции - это когда функция назначается как объект переменной «var» (или «let» / «const»).
var myFunc = function (params){ //function body }
Подъем здесь зависит от того, какой из «var» или «let» / «const» используется для объявления.
Например:
<script> function myBigFunction() { console.log(additionFunc(2,5)); //7 //addition function was defined using Function declaration. console.log(subtractionFunc(5,2)); //Uncaught TypeError: subtractionFunc is not a function. //This error shows that subtractionFunc is declared but is not recognized as a function yet. console.log(subtractionFunc) //undefined console.log(multiplicationFunc(2,5)); //Uncaught ReferenceError: multiplicationFunc is not defined function additionFunc(a, b){ return a + b; } var subtractionFunc = function(a, b){ return a - b; } let multiplicationFunc = function(a, b){ return a * b; } console.log(additionFunc(2,5)); //7 console.log(subtractionFunc(5,3)); //2 console.log(multiplicationFunc(2, 5)); //10 } </script>
Функция «addFunc» была определена с помощью «объявления функции» и, таким образом, поднимается, что позволяет нам вызывать ее перед ее определением.
Функция «subtractionFunc» была определена с использованием «выражения функции» с «var», и поэтому ее объявление поднимается, давая ей значение undefined до ее инициализации.
Функция multiplicationFunc была определена с помощью выражения function с let и поэтому не поднимается вообще.
Вот и все подъемы!
Ваше здоровье!