Поднять, с точки зрения непрофессионала, означает поднять что-то. С тех пор, как я начал изучать JS, я понимал подъем как механизм, в котором переменные и функции перемещаются в верхнюю часть своей области видимости, но не больше. Давайте разберемся с неправильным представлением о том, как на самом деле работает подъемник, приведем кучу примеров.

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

Давайте разрушим миф и разберемся, что происходит под капотом. Наш код остается неизменным, он никуда не денется. Когда движок JS обрабатывает код, создается контекст выполнения: -

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

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

Необъявленная переменная всегда имеет тип undefined, также во время выполнения.

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

Давайте разберемся с подъемом на серии примеров:

var

Давайте разберемся, как подъем работает с var-

Мы ожидали, что будет зарегистрирован 1, но он был undefined. Как объяснялось ранее, на этапе создания во время компиляции кода var hoist сохраняется в памяти. Затем движок JS сам добавит значение заполнителя, которое не определено. Позже, на этапе выполнения, когда в нашем коде выполняется присвоение, он обновит это значение вместо undefined.

В приведенном выше примере мы получили ошибку ссылки, поскольку интерпретатор JS сообщает, что переменная нигде не может быть найдена в памяти, поэтому она не определена.

функции

Давайте посмотрим, как будет работать подъем с функцией.

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

Вам должно быть интересно, как мы можем получить доступ к a за пределами его области. Хотя мы не можем получить доступ к b вне его области действия, но важно отметить, что при присвоении значения необъявленной переменной (a в нашем примере ), при выполнении неявно создается как глобальная переменная. Однако для доступа к необъявленной переменной, такой как a, должен выполняться код, в котором она назначается, иначе будет выдана ошибка, как показано ниже.

Давайте посмотрим еще на пример

В приведенном выше коде var b будет поднят в пределах своей области действия, а затем будет инициализирован значением undefined, позже на этапе выполнения, когда JS-движок войдет в ту строку кода, где мы присвоили значение, он проверит, выполнено ли какое-либо присвоение var b, соответственно он обновит значение b, иначе оно останется неопределенным.

Примечание. Стрелочные функции и функциональные выражения не поднимаются.

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

Ниже показан пример, показывающий, что стрелочная функция также не поднимается.

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

Назначение переменной вместо объявления функции

Объявление функции вместо объявления переменной

Класс

Давайте посмотрим, как подъем работает в классе JS. Мы можем классифицировать класс как объявление класса и выражение класса.

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

Ваш линтер отобразит сообщение «Класс« Автомобиль », использованный до его объявления». Следовательно, чтобы получить доступ к свойствам класса, нам нужно сначала объявить его, а затем получить к нему доступ. Чтобы приведенный выше код работал, мы должны написать его так:

Следовательно, на этапе создания класс будет поднят, но останется неинициализированным. Когда JS-движок оценивает оператор класса, он инициализирует класс своим значением.

2. выражение класса

выражение класса не поднимается. Давайте посмотрим на это на примере

Правильный способ реализовать это -

let и const

С введением новых изменений в ES6 + появились let и const. Переменные, объявленные с помощью ключевых слов let и const, имеют блочную область видимости. Их тоже поднимают, но не так, как поднимают вар. На этапе создания они сохраняются в памяти, но, в отличие от var, не инициализируются. Они остаются неинициализированными до тех пор, пока их назначение не будет оценено во время выполнения или на этапе выполнения механизмом JS.

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

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

В приведенном выше коде во время компиляции переменная car сохраняется в памяти, но она не будет инициализирована каким-либо значением, пока JS-движок во время фазы выполнения / выполнения не выполнит эту строку кода. Поскольку в этот раз он не имеет значения (в момент объявления JS-движок проверит, присвоено ли какое-либо значение), будет присвоено значение undefined. После этого будет присвоено 6, и значение будет обновлено. Посмотрим еще один экзамен

Note-let и const инициализируются только на этапе выполнения. Время между объявлением переменной и инициализацией - это временная мертвая зона, и доступ в этом окне вызовет ошибку ссылки.

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

Заключение

  1. Всегда объявляйте и инициализируйте переменные перед их использованием.
  2. По возможности используйте let и const.
  3. Чтобы избежать ошибок, связанных с подъемом, настоятельно рекомендуется использовать «строгое использование».

Это все, что нам нужно знать о Hoisting. Если вам понравилась эта статья, нажмите кнопку хлопка. Также приветствуются предложения.