Для TL; DR утопить прокрутку

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

Большинство разработчиков, которые плохо знакомы с JavaScript, когда их спрашивают о подъеме, сначала подумают о переменных let vs var, о том, как одну можно использовать перед объявлением (var), а другую - нет. (позволять). И они правы, поскольку основное определение подъема, которое можно найти во многих популярных статьях, звучит так:

Подъем - это стандартное поведение JavaScript, заключающееся в перемещении объявлений var вверх.

Таким образом, можно физически (в нашем коде) использовать переменную var перед ее объявлением, при этом использование переменной let перед ее объявлением (физически в нашем коде) вызовет ошибка.

Ну, не совсем так ... Давайте перемотаем назад и посмотрим, что на самом деле происходит, когда JavaScript Engine выполняет наш код.

Сначала давайте вспомним, что каждая строка в JavaScript выполняется внутри контекста выполнения (функционального контекста выполнения, если код находится внутри функции, и глобального контекста выполнения, если нет).

Поэтому, когда движок JavaScript выполняет наш код, он устанавливает глобальный контекст выполнения в два этапа: этап создания и этап выполнения.

Этап создания: JavaScript создаст глобальный объект (окно, поскольку мы находимся на глобальном уровне), переменную this, используемую для доступа к глобальному объекту, и внешнюю среду (которая будет иметь значение null так как мы находимся на глобальном уровне)…

Затем он установит место в памяти для всех переменных и функций или просто вызовет «Подъем»! Механизм JavaScript будет читать наш код и каждый раз, когда он находит объявление переменной на глобальном уровне, резервирует для него место в памяти, устанавливая его значение на undefined, и каждый раз, когда он находит объявление функции. он зарезервирует для него место в памяти и полностью распределяет его.

Этап выполнения: после создания глобального контекста с его переменной средой JavaScript Engine начинает выполнение нашего кода построчно. Таким образом, к тому времени, когда движок JavaScript переходит ко второй строке в нашем примере на этапе выполнения, он уже знает, что у нас есть пространство, выделенное для переменной myVillain со значением undefined , что означает, что присвоение нового значения переменной совершенно нормально и не приведет к возникновению ошибки (вы знаете… поскольку переменная уже определена в переменной среде!).

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

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

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

Ответ: нет. Как и var, объявления let также поднимаются во время создания контекста выполнения. Нам просто запрещено использовать их, пока физически не попадет в строку нашего кода, в которой объявлена ​​переменная let. Он все еще существует в памяти, нам просто не разрешено его использовать! Так что нет, подъем работает одинаково для объявлений functions, var, let И const.

Вот некоторые примеры:

Теперь, когда вы усвоили концепцию подъема и поняли, что происходит на самом деле, и что код не «волшебным» физически перемещается наверх, у меня есть небольшая викторина для вас (базовая для некоторых, но сложная для другие).

Что будет в результате следующего:

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

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

Итак, в первом примере при подъеме движок JavaScript установит пространство в памяти для атаки как var и установит его значение на undefined. , что является нормальным поведением JavaScript. Помнить? Каждые var, let и const устанавливаются на undefined в области памяти на этапе создания контекста выполнения. .

Если мы посмотрим на выдаваемую ошибку «Uncaught TypeError: атака не является функцией», она очевидна: атака не является функцией просто потому, что она не определена. Какое значение получает движок JavaScript, когда он ищет атаку в своей переменной среде на этапе выполнения.

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

TL;DR

1- Подъем означает, что пространство памяти выделяется для переменных и функций во время создания контекста выполнения. И переменным присваивается значение undefined.

2- Все объявления переменных: var, let и const подлежат подъему.

3. Нам не разрешается использовать переменные let и const до того, как физически попадет в строку их объявления в коде. Даже если они существуют в памяти и для них установлено значение undefined.

4- При использовании функциональных выражений мы создаем объект, который возвращается переменной, который будет обрабатываться как… ну, переменная. Это означает, что он будет поднят, и ему будет присвоено значение undefined. Другими словами: вы не можете использовать функцию до ее объявления, если она объявлена ​​как выражение функции.

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

6- Да, в JavaScript функции являются объектами.

Каутар ЛАГДАНИ



Примечание команды Plain English

Вы знали, что у нас четыре публикации? Проявите немного любви, предложив им следующие слова: JavaScript на простом английском, AI на простом английском, UX на простом английском , Python на простом английском - спасибо и продолжайте учиться!

Кроме того, мы всегда заинтересованы в продвижении хорошего контента. Если у вас есть статья, которую вы хотели бы отправить в какую-либо из наших публикаций, отправьте электронное письмо на адрес [email protected] с вашим именем пользователя Medium и тем, о чем вы хотите написать, и мы вернуться к вам!