VAR vs LET vs CONST — как правильно выбрать!

Введение

Хотя большинство из нас, разработчиков frontend, постоянно определяют переменные JavaScipt, я столкнулся с тем, что многие, особенно младшие разработчики, на самом деле не знают или на самом деле не заботятся о различиях в том, как они объявляют переменные в JS.

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

Почему это важно?

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

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

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

Хотя JavaScript неплох, он все же позволяет вам делать кучу очень странных вещей, о которых вы, как разработчик, должны знать!

Обзор

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

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

Значение области видимости может быть еще неясно, но мы сосредоточимся на этом вопросе в следующем примере.

Подъем

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

  1. Поднятие значения → доступ к значению переменной ДО объявления переменной.
  2. Поднятие объявления → ссылка на переменную до объявления, но со значением, присвоенным undefined .
  3. Лексическое поднятие → ссылка на переменную перед объявлением или вне ее области действия приводит к ошибке ссылки.

Обычно объявления функций (function , async function ) подлежат подъему типа 1, var является примером типа 2 и let , const и class (лексические объявления) ведут себя как подъем типа 3.

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

VAR — декларация

Объявление var в основном является пережитком времен до ES6, но все еще регулярно появляется в современных приложениях.

На мой взгляд, var не следует использовать ни в каких современных приложениях, кроме, может быть, очень немногих исключений.
❌ — ПРОСТО НЕ ИСПОЛЬЗУЙТЕ ЭТО!

Во-первых, var находится в области действия и, таким образом, может вызвать чертовски много проблем! Давайте посмотрим на пример:

Как видите, rusty доступен внутри И вне оператора if, поскольку интерпретатор перемещает его в верхнюю часть родительской области! 🤯

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

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

Кроме того, поскольку var ведет себя как подъем типа 2, переменная инициализируется с помощью undefined и, таким образом, даже имеет значение до ее фактического объявления. Вот пример:

Мы видим, что rusty доступен еще до того, как переменная была присвоена!

Повторное объявление переменных VAR

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

LET-декларация

Команда JS, очевидно, также согласилась с тем фактом, что поведение var может быть проблематичным, и поэтому с появлением ES6 представила новые параметры объявления блочной области let и const .

Если вы не знаете, как объявлять свои переменные, используйте let! Это предпочтительный способ объявления переменных в современных JS-приложениях, который вызывает наименьшее количество проблем.

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

Как видите, rusty теперь имеет блочную область и живет только внутри блока, в котором он был определен! Это означает, что после того, как этот блок завершится, выделение станет предметом сборки мусора, так как к нему больше нельзя будет получить доступ. Это не только может повысить производительность, но и значительно снизить риск переопределения глобальных значений и типов.

Более того, let можно переназначить, но НЕ повторно объявить! Это означает, что вы по-прежнему можете назначать новые значения переменной, но не можете выделить для нее совершенно новый слот памяти. Итак, пока это справедливо

это не

Наконец, в отличие от var , let не инициализируетсяс помощью undefined — на самом деле он вообще не инициализируется, поскольку ведет себя как подъем типа 3.Поэтому , попытка доступа к переменной до ее фактического объявления приводит к ошибке ссылки:

CONST-декларация

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

Вот и все! 🚀

Я надеюсь, что эта статья поможет вам немного больше узнать об объявлениях переменных в JS и их влиянии на вашу работу! Возможно, вы даже начнете понимать педантичных сторонников бэкенд-инженера за строгие правила в языках программирования. 👀

Как всегда, обращайтесь, если есть какие-либо вопросы или комментарии! 🙏