Подъем в JavaScript

Введение Подъем - это поведение JavaScript, широко известное тем, что делает переменные и функции доступными для использования до того, как переменной будет присвоено значение или определена функция. Фактически, он помещает объявления переменных, функций и классов в верхнюю часть их области видимости (глобальной области или функции) перед выполнением. На самом деле JavaScript не перемещает и не добавляет код в объявления подъема. Эти объявления помещаются в память на этапе компиляции интерпретатора, что делает их доступными.

Вступление

Подъем - это поведение JavaScript, обычно известное тем, что делает переменные и функции доступными для использования до того, как переменной будет присвоено значение или определена функция. Фактически, он помещает объявления переменных, функций и классов в верхнюю часть их области видимости (глобальной области или функции) перед выполнением.

На самом деле JavaScript не перемещает и не добавляет код в объявления подъема. Эти объявления помещаются в память на этапе компиляции интерпретатора, делая их доступными до выполнения кода.

В этой статье мы узнаем о подъеме и о том, как он влияет на переменные, функции и классы.

Подъемные переменные

Одним из ключевых аспектов подъема является то, что объявление помещается в память, а не значение.

Посмотрим на пример:

 console.log(name); // Prints undefined, as only declaration was hoisted 
 var name = "John"; 
 console.log(name); // Prints "John" 

Это происходит потому, что JavaScript видит, что у нас есть name переменной в области видимости, и помещает его в память. Переменным, объявленным с помощью var , присваивается значение undefined пока им не будет присвоено другое значение.

Переменный подъем с помощью let и const

Разработчики JavaScript редко используют var в пользу let и const представленных в ECMAScript 2015 (обычно называемых ES6). Поднимаются переменные, объявленные с помощью let и const . Однако они не инициализируются undefined значением или каким-либо другим значением. Следовательно, если они используются до инициализации, мы получим ReferenceError .

Давайте повторно воспользуемся тем же примером, но let использовать let вместо var :

 console.log(name); // Uncaught ReferenceError: Cannot access 'name' before initialization 
 let name = "John"; 
 console.log(name); 

Приведенный выше код вызывает ошибку ReferenceError в первой строке и завершает выполнение.

const было добавлено для введения неизменяемых значений в JavaScript - значений, которые нельзя изменить после его инициализации. Таким образом, при использовании const мы должны объявить и присвоить значение переменной. Если мы этого не сделаем, мы получим SyntaxError :

 console.log(name); // Uncaught SyntaxError: Missing initializer in const declaration 
 const name; 

И, как и let , мы получаем ReferenceError когда пытаемся использовать константу до ее инициализации:

 console.log(name); // Uncaught ReferenceError: Cannot access 'name' before initialization 
 const name = "John"; 
 console.log(name); 

Подъемные функции

Объявления функций подняты в JavaScript. Объявление функции начинается с ключевого слова function , за которым следует ее имя и аргументы в скобках, а затем ее тело. Рассмотрим следующий код:

 let first_name = "Stack"; 
 let last_name = "Abuse"; 
 
 let result = concat(first_name, last_name); 
 console.log(result); // StackAbuse 
 
 function concat(x, y) { 
 return x + y; 
 } 

Как и в случае с переменными, JavaScript помещает функцию в память перед выполнением кода в этой области. Следовательно, подъем позволяет нам вызывать concat() до того, как она будет определена позже в коде.

Пока объявления функций поднимаются, функциональные выражения работают иначе. Выражение функции - это когда мы назначаем переменную функции. Например, приведенный ниже код вернет ошибку:

 func_express(); // TypeError: func_express is not a function 
 
 var func_express = function () { 
 console.log('This the function expression is not a function'); 
 }; 

JavaScript возвращает TypeError потому что, в отличие от объявления функции, была поднята только переменная. Когда переменные, объявленные с помощью var , поднимаются, им присваивается значение по умолчанию undefined . Затем JavaScript выдает ошибку, потому что значение переменной в этот момент времени не является функцией.

Подъем функций с помощью стрелочных функций

ECMA2015 представил новый способ создания анонимных функций, стрелочные функции. Они определяются парой скобок, содержащей 0 или более аргументов, стрелкой => и телом функции в фигурных скобках. Что касается подъема, они действуют как другие функции. Например:

 arrow_func_express(); // TypeError: arrow_func_express is not a function 
 
 var arrow_func_express = () => { 
 console.log('This the arrow function is not a function'); 
 }; 

При использовании стрелочных функций или любого другого функционального выражения мы всегда должны определять функцию, прежде чем использовать ее в нашем коде. Это правильный способ использования выражения функции:

 let arrow_func_express = () => { 
 console.log('This function expression will work'); 
 }; 
 
 arrow_func_express(); // This function expression will work 

Подъемные классы

Объявления классов подняты в JavaScript. Объявление класса не инициализируется при поднятии. Это означает, что хотя JavaScript может найти ссылку на созданный нами класс, он не может использовать этот класс до того, как он будет определен в коде.

Возьмем следующий пример, который вызывает ошибку при попытке доступа к классу до его определения:

 var person = new Person(); 
 person.name = "Jane"; 
 person.age = 25; 
 
 console.log(person); // Uncaught ReferenceError: Cannot access 'Person' before initialization" 
 
 class Person { 
 constructor(name, age) { 
 this.name = name; this.age = age; 
 } 
 } 

ReferenceError аналогична тому, что происходит, когда мы пытаемся получить доступ к переменной, объявленной с помощью let или const до ее инициализации в нашем скрипте.

Выражения класса, в которых мы назначаем определение класса переменной, ведут себя аналогично выражениям функций. Поднимаются их объявления, но не их присвоенное значение.

Давайте возьмем наш предыдущий пример и вместо этого воспользуемся выражением класса:

 var person = new Person(); 
 person.name = "Jane"; 
 person.age = 25; 
 
 console.log(person); // Uncaught TypeError: Person is not a constructor" 
 
 var Person = class { 
 constructor(name, age) { 
 this.name = name; 
 this.age = age; 
 } 
 } 

Когда переменная Person поднимается, ей присваивается значение undefined . Поскольку мы не можем использовать undefined значение в качестве класса, JavaScript выдает TypeError .

При работе с объявлениями классов или выражениями классов мы всегда должны определять класс раньше в нашем коде, чтобы использовать его. Правильный способ использования класса следующий:

 class Person { 
 constructor(name, age) { 
 this.name = name; this.age = age; 
 } 
 } 
 
 var person = new Person(); 
 person.name = "Jane"; 
 person.age = 25; 
 
 console.log(stack); // Person { name: 'Jane', age: 25 } 

Заключение

Подъемы JavaScript, объявления переменных, функций и классов. В этой статье показано влияние подъема на то, как мы пишем код JavaScript.

Объявления функций могут использоваться до их определения из-за подъема. Однако, чтобы свести к минимуму наши шансы получить undefined значения, а также ошибки ссылок или типов, безопаснее использовать переменные, выражения функций и классы после того, как они определены в нашем коде.

comments powered by Disqus