Что означает let в javascript
Перейти к содержимому

Что означает let в javascript

  • автор:

Javascript let keyword for declaring block scoped variables

When it comes to writing modern javaScript code the let keyword is available for declaring block level, rather than function level scoped variables. When it comes to getting into variable scope that might be a topic for another post, but I will be touching base with that here as it is called for when it comes to any post that has to do with the let keyword compared to traditional option known as var.

When it comes to a node.js environment where I have control over the version of node.js is used, and can use a modern version that supports let there are not any concerns when it comes to the question of code breaking on older platforms. At least when it comes to me using my own code in may own environments where I know that will never be the case. That issue is of greater concern when it comes to front end development where there is less control over the environment in which the javaScript code runs when thinking about older browsers. Still as time goes by this will become less of an issue, and block level scope for me is a welcome addition to javaScript, so in this post I will be writing about some concerns when it comes to the use of let in a javaScript project.

So the time will come when there will be basically no point at all of using the var keyword anymore for the same reasons why it no longer makes sense to go out of ones way to make sure that their code will not break in Internet explorer 5. It is all about looking at the browser vendor and version data of a sites analytics, and when I do so it looks like most people are using modern evergreen browsers these days. So if it has not happened for you yet it is only a matter of time until it is just a question of using let, const, or both. If you do want to just use only one, like the good old days of var only, then the choice is clear, the choice is let, so lets get into why that is.

1 — javaScript let keyword basics

When the let keyword is used this results in a block level variable scoped value. So the variable can also be accessed from within a block of code in which it is declared, this can be considered a major improvement from the older javaScript specs that support function level only scope. Conciser the following example.

This code results in an error, but not just because the value of n is lower than 42. If I where to replace all instances of let with var the value undefined will be logged rather than the error message ‘a is not defined’ because of the variable hoisting aspect of the var keyword.

In addition even if I where to increase the value of n so that the code in the body of the if statement runs, I will still get the same error message. This is of course what is expected as the whole point of using let is to have block level scope, rather than function level scope that var alone can achieve.

2 — No older browser support for javaScript let

As I have stated one of the biggest concerns with using let is backward compatibility. Unlike many other new methods and features that have been introduces in late es2015+ javaScript specs the let keyword can not be polly filled. When thinking in terms of older platforms there just is not any block level variable scope.

Of course there are ways of writing javaScript in a way in which I am taking advantage of modern features such as let, and then also maintain an alternative work of that JavaScript that will run on older platforms as well. There are also tools that can be used to help automate that process, but for the most part that complicates things.

It is easier to just continue to write javaScript code in a way in which it will work in older browsers while still functioning just find in more modern browsers as well. I have this attitude where as long as I make my code clean, and minimal the process of modernizing it should not be to hard or time consuming.

When it comes to server side javaScript though the use of the javaScript let keyword is not as big of a cover though of course, assuming that I have control over the version of node.js to use, and it is a late version that supports the javaScript let keyword along with other modern javaScript features.

3 — Redeclaring variables

One thing that comes up with using let over the traditional var is redeclaring a variable with the let keyword over var. The var keyword is more forgiving with this, allowing for a variable to be redeclared over and over again in the same bit of code. The let keyword on the other hand will throw a nasty error if this is done.

For the most part this is not a big problem for me, as I generally do not do this when writing legacy javaScrip style code. There may be some rare extenuating circumstances in which this might get annoying, but I am sure I could find a way to manage.

4 — Simulating block scope with functions.

One of the draw backs of using var over let is of course not having block level variables scope. When it is just var that is used it is a situation in which there is function level scope only. That being said it is possible to simulate block scope with self executing function expressions however.

It may be ugly, but for the most part the same desired effect is achieved.

5 — Conclusion

The use of javaScript let is a nice addition when it comes to later javaScript specs. Although browser support is decent with javaScript let these days depending on how far I want to push backward compatibility back, I still find myself shying away from using in when writing client side code at least. When it comes to an environment in which I have control however there is less reservations about using late javaScript features such as the let keyword, and arrow functions.

Leaning a thing or two about variable scope is something that a developer should become areas of when first getting started with javaScript. If you are still fairly new to javaScript you might want to check out my main getting started with javaScript post.

Чем различаются var, let и const в JavaScript

На практике разбираемся, чем различаются var, let и const и когда их использовать.

Иллюстрация: Катя Павловская для Skillbox Media

Евгений Кучерявый

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

Содержание:

Объявление, инициализация и область видимости переменной в JavaScript

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

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

Объявить переменную — значит ввести новый идентификатор в программу.

До выхода стандарта ECMAScript 6 переменные в JavaScript объявляли только с помощью ключевого слова var:

Когда интерпретатор JavaScript находит очередное объявление с var, он выделяет место в памяти и по умолчанию присваивает элементу значение undefined — то есть «неопределённое». Также undefined можно получить, если обратиться к несуществующим элементам массива и свойствам объекта.

Обращение к неопределённому значению может привести к непредсказуемым ошибкам, поэтому рекомендуется как можно раньше давать переменным начальное значение — то есть инициализировать их. Делается это с помощью оператора =:

Мы можем выводить переменную best_podcast на экран и перезаписывать её сколько угодно. Главное — чтобы в момент обращения программа её «видела». Да, в разные моменты времени переменные то скрываются, то появляются в поле зрения интерпретатора JavaScript.

Часть программы, в которой доступен тот или иной идентификатор, называют областью видимости переменной.

В зависимости от области видимости в JavaScript различают локальные (functional scope) и глобальные (global scope) переменные. Локальные создаются внутри функции и доступны только в её пределах. А глобальные объявляются вне функций и видны в любой точке программы. Именно в работе с областью видимости и заключаются различия между var и let.

Как работает var и что с ней не так

Переменная var, созданная вне функции, действует как глобальная переменная — она доступна из любой части скрипта.

Если же создать переменную с помощью var внутри функции, то она будет локальной, то есть доступной только в этой функции:

Это позволяет создавать переменные с одинаковыми названиями и обращаться к внешним переменным через специальный объект window:

Не стоит привыкать к var. Использование этого ключевого слова в 2022 году считается плохой практикой по нескольким причинам.

Отсутствие блочной области видимости. Var-переменная, созданная в блоке if‑else или цикле, доступна за пределами своего блока. Например, в C++ или Java не получится получить доступ к счётчику цикла нигде, кроме тела этого цикла, а вот в JavaScript, если счётчик объявлен как var, — получится легко. Это практически всегда приводит к труднораспознаваемым логическим ошибкам.

Повторное объявление. Переменные var можно создавать повторно, и компилятор не будет ругаться. Почему это плохо? Допустим, в вашем JS-файле 4000 строк кода. Вы объявили на 5-й строке переменную books, которая хранит количество PDF-книг на сайте. А затем, добравшись до 3005-й строки, забыли об этом и создали другую переменную books — только теперь она хранит количество книг в корзине покупателя. Даже если вы уверены, что всегда сможете отличить одну переменную от другой, то программисты, которые будут работать с вашим кодом, точно не скажут вам спасибо.

«Поднятие» переменной, или hoisting. Все переменные var считаются объявленными перед запуском скрипта. При этом они остаются undefined до тех пор, пока не выполнится код инициализации.

Если запустить приведённый выше код, компилятор выведет название лучшего подкаста про IT. Но почему? Ведь мы инициализировали переменную до того, как её определили. По «нормальной» логике интерпретатор должен вернуть сообщение об ошибке, потому что блок if никогда не выполнится и переменная не будет определена. Но с var такие парадоксы — обычное дело.

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

Как работает let и чем она отличается от var

Ключевое слово let лишено недостатков своего предшественника. Переменные, объявленные с его помощью, нельзя объявить повторно — программа выдаст ошибку. Let-переменные тоже «всплывают», но при попытке обратиться к ним до инициализации вы получите ошибку ReferenceError.

Но главное — такие переменные имеют блочную область видимости. А значит, они доступны только внутри того блока <>, в котором были созданы:

Вот как различается поведение счётчика цикла, если его создавать с помощью var и с помощью let:

//Переменная i доступна за пределами цикла

//Переменная i доступна только внутри цикла
//Попытка использовать её приведёт к ошибке

В остальном поведение этих переменных идентично.

Объявление констант с помощью оператора const

С помощью ключевого слова const создаются константы. Например, физические и математические величины.

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

Например, в них можно хранить объекты из DOM:

Также стоит отметить, что неизменяемым сохраняется сам объект, а не его поля:

Что касается областей видимости, то const ведёт себя как let — разницы между ними нет.

Обратите внимание: let и const являются частью стандарта ECMAScript 6, который поддерживается не всеми браузерами. Заранее ознакомьтесь с таблицей совместимости.

Заключение

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

Var, let и const в JavaScript

Alice

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

Чтобы по-настоящему понять разницу между var, let и const, нам необходимо разобраться в следующих понятиях:

  • Объявление переменной;
  • Инициализация переменной;
  • Область видимости;
  • Механизм hoisting («поднятие»).

Объявление переменной

Объявление переменной — это процесс введения нового определения в программу или, если быть точнее, в область видимости. В JavaScript переменные изначально приобретают значение undefined, когда мы объявляем ключевое слово var (это автоматически выполняется интерпретатором).

Инициализация переменной

Инициализация переменной — это процесс присваивания значения переменной. Поэтому, когда мы определяем связь между ключевым словом var, интерпретатор присваивает значение undefined.

Область видимости

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

Существует 2 типа области видимости:

  • Функциональная область видимости;
  • Блочная область видимости.

Функциональная область видимости

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

Блочная область видимости

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

Поднятие

В веб-документации MDN говорится:

«Поднятие — это термин, использование которого вы не найдете ни в одной нормативной документации JavaScript до спецификации языка ES2015. Предполагалось, что поднятие — это обобщенный способ видения того, как работает контекст исполнения (особенно создание и исполнение стадий) в JavaScript. Однако это понятие по началу может сбивать с толку.

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

Как можно упростить оценку интерпретатора JS для кода выше:

Оператор var объявляет переменную, опционально присваивая ей значение. Любая переменная, объявленная оператором var, имеет функциональную область видимости и идентифицирует объявленные переменные с помощью ключевого слова var. Такие переменные поднятые, а их первоначальное значение — undefined.

Оператор let объявляет локальную переменную. Любая переменная, объявленная с помощью let, имеет блочную область видимости. Значения подняты и не инициализированы.

Связи let создаются сверху области видимости конкретного блока, содержащего определение, часто называемого поднятием. В отличие от переменных, объявленных с помощью var, которые начинаются со значения undefined, переменные let не инициализируются, пока им не присвоится значение. Обращение к переменной до инициализации вызовет Reference Error (ошибка использования несуществующего названия).

const

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

Следовательно, const должен быть всегда инициализирован при объявлении, иначе возникает ошибка.

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

Один последний факт:

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

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

В нашем случае интерпретатор не найдет ‘isGloballyAvailable’ даже в глобальной области видимости, поэтому он автоматически туда ее добавит.

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

Так, когда использовать var, let или const?

ES2015(ES6) представил let и const. Зачем JavaScript разработчикам их вводить? Может, чтобы исправить проблемы, возникающие с var, или для улучшения читабельность кода?

Одна главная проблема с var связана с тем, что он позволяет переназначать переменные в коде, из-за чего не выбрасываются ошибки. Это приводит к различным побочным эффектам в коде.

Распространенное мнение, которое сходится с моим:

Всегда отдавайте предпочтение const, если значение, присвоенное переменной, не изменится. Это подскажет будущим разработчикам, что у переменной неизменное значение.

Когда использовать var, let и const в Javascript [перевод статьи Tyler’а McGinnis]

Привет, Хабр! Представляю вашему вниманию перевод статьи «var vs let vs const in JavaScript» автора Tyler McGinnis.

image

В этой статье вы узнаете 2 новых способа для создания переменных в Javascript (ES6), let и const. На протяжении этой статьи мы рассмотрим разницу между var, let и const, а также смежные темы такие как: “область видимости функции против блочной области видимости“, “поднятие” переменных и иммутабельность.

Если вы предпочитаете видео, посмотрите это (оригинал на английском):

ES2015 (или ES6) представил нам 2 новых способа для создания переменных, let и const. Но прежде чем мы углубимся в различия между var, let и const, имеются некоторые темы, которые вам следует узнать в первую очередь. Это объявление переменных и их инициализация, область видимости (особая область видимости функции) и “поднятие”.

Объявление и инициализация переменных

Объявление переменной вводит новый идентификатор.

Выше мы создаем новый идентификатор который мы назвали “declaration”. В Javascript, при создании, переменные инициализируются со значением undefined. Это означает, что если мы попробуем вывести нашу переменную declaration, мы получим undefined.

И так, мы вывели переменную declaration и мы получили undefined.

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

И так, здесь мы инициализировали переменную declaration записывая в неё строку.

Это приводит нас к следующему понятию, область видимости.

Область видимости

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

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

Теперь давайте взглянем на более продвинутый пример. Скажем, у нас есть массив prices и нам требуется функция, которая принимает этот массив, а так же переменную discount, и возвращает нам новый массив цен со скидками. Конечная цель может выглядеть примерно так:

И реализация может выглядеть примерно так:

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

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

Оно не сломано, просто работает немного странно. На самом деле нет никаких причин иметь доступ к i, discountPrice и finalPrice за пределами цикла for. Это не приносит нам никакой пользы и может даже принести нам вред в некоторых ситуациях. Однако, так как переменные объявлены при помощи var, они входят в область видимости функции и вы можете получить к ним доступ.

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

“Поднятие”

Помните, ранее было сказано “В Javascript, при создании, переменные инициализируются со значением undefined “. Оказывается это и означает “поднятие”. Интерпретатор JavaScript назначает объявленным переменным значение undefined во время фазы называемой “Создание”.

Для более подробного изучения фазы Создания, “Поднятия” и областей видимости прочтите данную статью: “The Ultimate Guide to Hoisting, Scopes, and Closures in JavaScript”.

Давайте взглянем на предыдущий пример и увидим как “поднятие” влияет на него.

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

Теперь вы знаете все что нужно о var, теперь давайте наконец-то поговорим о главной цели, из-за которой мы здесь: в чем разница между var, let и const?

var, let или const

Для начала, давайте сравним var и let. Ключевое отличие между var и let это то, что let помимо глобальной области видимости и области видимости функции позволяет определять переменные в области видимости блока. Это означает, что переменная созданная при помощи ключевого слова let доступна внутри “блока”, где она была создана, также и внутри вложенных блоков. Когда я сказал “блок”, я имел в виду что-либо окруженное фигурными скобками <>, например цикл for или оператор if.

И так, давайте вернемся к нашей функции discountPrices в последний раз.

Вспомните, что мы вправе вывести i, discountPrice, и finalPrice за пределами цикла for, так как они были объявлены при помощи var, а переменные объявленные при помощи ключевого слова var ограничены областью видимости функции. Но что же произойдет теперь, если мы изменим var на let и попробуем запустить наш код?

Мы получили ReferenceError: i is not defined. Что говорит нам о том, что переменная, объявленная при помощи let, ограничена областью видимости блока, а не функции. Попытайтесь обратиться к i (или discountedPrice или finalPrice) за пределами “блока”, где они были объявлены, и это выдаст нам ошибку обращения, как мы только что увидели.

Следующие различие связано с “поднятием”. Ранее мы сказали, что определение “поднятия” это: “Интерпретатор JavaScript назначает объявленным переменным значение undefined во время фазы называемой “Создание”». Мы так же увидели это в действии при помощи вызова переменной до её объявления (вы получили undefined).

Я не могу вспомнить ни одного случая использования, когда вы на самом деле хотели бы получить доступ к переменной до её объявления. Кажется, что получить ReferenceError было бы лучше, чем получить undefined.

По факту, это и есть то что делает let. Если вы попытаетесь доступ к переменной до её объявление при помощи let, вместо получения undefined (как это было при объявлении при помощи var), вы получите ReferenceError.

let или const

Теперь вы понимаете разницу между var и let, что же о const? Оказывается, const почти такая же как и let. Однако есть одно отличие: если вы однажды присвоили значение используя const, вы не сможете его изменить на другое.

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

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

Заметьте, что изменения свойства объекта не является его перезаписью, так что даже если объект объявлен при помощи const, это не означает, что вы не можете изменить какие-либо из его свойств. Это только значит, что вы не можете перезаписать этот объект.

Теперь, наиболее важный вопрос, на который ещё не было ответа: что следует использовать var, let или const? Самое популярное мнение, и мнение которого придерживаюсь я, это использовать всегда const, пока вы не знаете будет ли переменная изменяться. Причина этого в том, что используя const вы даете понять себе и будущим разработчикам, которые должны прочитать ваш код, что эта переменная не должна изменяться. Если её потребуется изменить (например в цикле for), просто используйте let.

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

Теперь непопулярное мнение, хотя оно все ещё имеет обоснование, это то что вы никогда не должны использовать const, несмотря на то что вы пытаетесь показать, что эта переменная неизменна, как мы видели выше, это не совсем так. Разработчики, которые придерживаются этого мнения всегда используют let пока нет переменных, которые на самом деле являются константами, такими как _LOCATION_ =….

Составим резюме выше сказанного, var ограничена областью видимости функции и если вы попытаетесь обратиться к такой переменной до её объявления вы получите undefined. const и let ограничены областью видимости блока и если вы попытаетесь обратиться к этим переменным до их объявления вы получите ReferenceError. И отличие между const и let это то, что значение, которое было присвоено const не может быть перезаписано, в отличие от let.

Первоначально данная статья была опубликована на tylermcginnis.com как часть курса Modern JavaScript

Спасибо за прочтение данного перевода, надеюсь вы познакомились для себя с чем-то новым и полезным. Буду рад увидеть обратную связь!

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

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