Что такое hoisting как он работает для переменных и функций

Поднятие в JS (Hoisting в Javascript + 3 примера)

В этой статье мы с вами разберемся как что такое, и как работает поднятие (Hoisting) в Javascript. Эта одна из базовых тем в ванильном JS и вы однозначно наткнетесь на нее в одном из интервью при устройстве на работу.

Поднятие в JS (пример с функцией)

Для нашего примера создадим функцию letsGo и попробуем ее вызвать до ее создания.

Наша функция запускается, и мы получаем строку «Go!!» в нашей консоли. Это происходит, так как срабатывает мехнаизм «поднятие» в Javascript.

То есть, «под капотом» компилятор JS «поднимает» все строчки, где объявляются функции на самый верх.

Ваглядит это так:

Теперь, давайте немного расширим наш пример и создадим еще одну функцию add.

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

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

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

Если решим написать то же самое, используя стрелочную функцию, тоже получим ошибку («поднятие» не работает):

Поднятие в Javascript (пример с переменной var)

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

То есть, когда мы выводим в лог значение переменной years, до ее создания, происходит следующее:

Обработчики Событий в JS (как работает addEventListener)

Замыкания в Javascript (что такое замыкание в JS + 3 примера)

Источник

Что такое Hoisting в JavaScript

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

И как пользоваться этим “поднятием”

Возможно, вы уже знаете, что переменные могут “подниматься”. “Hoisting” переводится с английского как “поднятие” и означает понятие, которое было придумано для того, чтобы можно было говорить о замыканиях в JavaScript без указания области видимости переменных.

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

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Теперь рассмотрим то, что, скорее всего, вообще не будет работать в других языках программирования. Вернемся к коду: передвинем вызов функции b() и вывод значения переменной а вверх, в начало кода.

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

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

Консоль выдает ошибку a is not defined (переменная а не определена).

Теперь помещаем переменную внутрь JS-файла.

Такой феномен называется “поднятием” (hoisting).

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

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

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

Вот код, который мы писали в начале.

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

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

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Следует помнить, что this создается внутри контекста выполнения программы. Затем создаётся внешнее окружение.

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

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

Но JavaScript не перемещает код вверх. На самом деле его движок выделяет место в памяти для всех переменных, лежащих в коде, еще до начала построчного выполнения программы.

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

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

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

Вот как делать не нужно.

Вместо этого лучше сделать так.

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

Сравнение var, let и const при поднятии

Как вы думаете, каким будет результат вывода программы?

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Эта ошибка всплывает из-за Временной мертвой зоны (Temporal Dead Zone), однако не стоит пугаться этого термина. Он обозначает период между созданием переменной и её инициализацией, когда мы не можем получить к ней доступ.

Значит ли это, что все переменные, объявленные с помощью let и const не “поднимаются” в коде? Нет, они тоже поднимаются.

Источник

Поднятие в JavaScript

Хочешь проверить свои знания по JS?

Подпишись на наш канал с тестами по JS в Telegram!

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

Что такое поднятие в JavaScript?

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

Дело в том, что интерпретатор JavaScript разделяет объявление и назначение значений для функций и переменных. Ваши объявления «поднимаются» вверх их области видимости перед выполнением.

Этот процесс называется поднятием. Именно благодаря ему мы можем использовать переменную foo в нашем примере еще до того, как она объявлена.

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

Поднятие переменных в JavaScript

Чисто в качестве напоминания: мы объявляем переменные при помощи операторов var, let и const. Например:

Мы назначаем значение переменной, используя оператор присваивания:

Во многих случаях объявление и присваивание значения комбинируются в один шаг:

Поднятие переменных, объявленных при помощи var

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

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

Теперь вы, вероятно, думаете: «Хм. Это как-то странно, что JavaScript позволяет получить доступ к переменным до того как они объявлены». Это поведение — необычная часть JavaScript. Оно может привести к ошибкам, поэтому использование переменной до ее объявления обычно нежелательно.

Поднятие переменных, объявленных при помощи let и const

Обратите внимание, что интерпретатор по-прежнему поднимает foo: сообщение об ошибке говорит нам, что где-то эта переменная инициализирована.

Временная мертвая зона

TDZ начинается в начале области видимости переменной и заканчивается ее объявлением. Обращение к переменной в TDZ приводит к выбросу ReferenceError.

Вот пример понятного блока, показывающего начало и конец временной мертвой зоны foo:

TDZ также присутствует в дефолтных параметрах функции, которые оцениваются слева направо. В следующем примере bar находится в TDZ, пока не получает значение по умолчанию:

Но этот код работает, потому что мы можем обратиться к foo вне ее TDZ:

typeof во временной мертвой зоне

Это поведение согласуется с другими примерами с let и const в TDZ, которые мы уже видели. Здесь мы получаем ReferenceError, потому что foo объявлена, но не инициализирована. Мы должны знать, что используем ее до инициализации.

Кроме того (и это удивительно), мы можем проверить тип несуществующей переменной и не получить ошибку. typeof безопасно возвращает строку:

Фактически, появление let и const сломало гарантию того, что typeof всегда возвращает строковое значение для любого операнда.

Поднятие функций в JavaScript

Объявления функций тоже поднимаются. Это позволяет нам вызывать функцию до ее объявления. Например, следующий код успешно запускается и выдает результат «foo»:

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

Если мы попытаемся вызвать переменную, которой было присвоено в качестве значения функциональное выражение, мы получим TypeError или ReferenceError — в зависимости от области видимости переменной:

Это отличается от вызова вообще не объявленной функции, который вызвал бы другую ошибку — ReferenceError:

Как использовать поднятие в JavaScript

Поднятие переменных

Если вы работаете над старой кодовой базой или вам еще по какой-то причине приходится использовать var, MDN рекомендует писать var-объявления как можно выше в области видимости. Таким образом скоуп ваших переменных будет яснее.

Вы также можете подумать над использованием правила no-use-before-define в ESLint, чтобы точно не использовать переменные до их объявления.

Поднятие функций

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

Вот вам надуманный пример:

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

Тем не менее, использование функций до их объявления — дело вкуса. Некоторые разработчики, например Wes Bos, предпочитают другой путь. Они помещают функции в модули, которые можно импортировать при необходимости. (Источник: Wes Bos).

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

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

Если вы полагаете, что определение функции настолько большое и сложное, что помешает читателю понять остальной файл, возможно, пора выделить это определение в модуль!»

Заключение

Спасибо за внимание! Надеюсь, эта статья помогла вам познакомиться с темой поднятия в JavaScript.

Источник

Поднятие или hoisting в JavaScript

Что такое «поднятие» и как оно работает в JavaScript.

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

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

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

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

JavaScript поднимает только объявления, а не инициализации. Если переменная объявлена и инициализирована после её использования, значение будет неопределенным (undefined). Например:

Если мы объявляем переменную после её использования, но предварительно инициализируем её, она вернет значение:

Функции полностью подняты. Означает, что объявлению функции, на этапе создания, было назначено место в памяти.

Поднятие const, let и var

Ключевое слово var

Приведенный выше код, из-за поднятия эквивалентен приведенному коду ниже.

Ключевые слова const / let

Источник

Что такое Hoisting в JavaScript

И как пользоваться этим “поднятием”

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Mar 28 · 6 min read

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Возможно, вы уже знаете, что переменные могут “подниматься”. “Hoisting” переводится с английского как “поднятие” и означает понятие, которое было придумано для того, чтобы можно было говорить о замыканиях в JavaScript без указания области видимости переменных.

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

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Тепе р ь рассмотрим то, что, скорее всего, вообще не будет работать в других языках программирования. Вернемся к коду: передвинем вызов функции b() и вывод значения переменной а вверх, в начало кода.

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

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

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Консоль выдает ошибку a is not defined (переменная а не определена).

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Теперь помещаем переменную внутрь JS-файла.

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Такой феномен называется “поднятием” (hoisting).

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

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

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

Вот код, который мы писали в начале.

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

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

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Следует помнить, что this создается внутри контекста выполнения программы. Затем создаётся внешнее окружение.

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

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

Но JavaScript не перемещает код вверх. На самом деле его движок выделяет место в памяти для всех переменных, лежащих в коде, еще до начала построчного выполнения программы.

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

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

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

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

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

Вот как делать не нужно.

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Вместо этого лучше сделать так.

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

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

Сравнение var, let и const при поднятии

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Как вы думаете, каким будет результат вывода программы?

Что такое hoisting как он работает для переменных и функций. Смотреть фото Что такое hoisting как он работает для переменных и функций. Смотреть картинку Что такое hoisting как он работает для переменных и функций. Картинка про Что такое hoisting как он работает для переменных и функций. Фото Что такое hoisting как он работает для переменных и функций

Эта ошибка всплывает из-за Временной мертвой зоны (Temporal Dead Zone), однако не стоит пугаться этого термина. Он обозначает период между созданием переменной и её инициализацией, когда мы не можем получить к ней доступ.

Значит ли это, что все переменные, объявленные с помощью let и const не “поднимаются” в коде? Нет, они тоже поднимаются.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *