что такое let в javascript

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

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

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

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

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

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

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

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

Области видимости var и let

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

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

Также можно создать переменные с одинаковым названием:

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

Что же касается let, то такие переменные доступны только внутри того блока <>, в котором они созданы:

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

varlet
for(var i = 0; i const создаются константы. Например, физические и математические величины.

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

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

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

Что же касается областей видимости, то const ведёт себя как let.

Заключение

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

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

Источник

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

В редакцию ES2015 были введены два новых важных ключевых слова JavaScript — let и const.

Эти два ключевых слова позволяют в JavaScript декларировать переменные и константы с областью видимости внутри блока.

До редакции ES2015 в JavaScript было только два типа области видимости — глобальная и внутри функции.

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

Переменные, декларированные глобально (вне какой-либо функции), обладают глобальной областью видимости.

Доступ к глобальным переменным можно получить из любого места программы на JavaScript.

Область видимости внутри функции

Переменные, декларированные локально (внутри какой-либо функции), обладают областью видимости внутри функции.

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

Область видимости внутри блока

Переменные, декларированные при помощи ключевого слова var, не обладают областью видимости внутри блока.

Т.е. доступ к таким переменным, декларированным внутри блока , можно получить и вне этого блока.

До редакции ES2015 в JavaScript не было области видимости внутри блока.

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

Передекларирование переменных

Передекларирование переменной при помощи ключевого слова var может вызвать проблемы.

Так, если передекларировать переменную внутри блока, то она будет перекларирована и за его пределами:

Решить эту проблему можно, если передекларировать переменную при помощи ключевого слова let.

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

Область видимости внутри цикла

Использование ключевого слова var в цикле:

Использование ключевого слова let в цикле:

В первом примере переменная, декларированная в цикле при помощи ключевого слова var, также передекрарирует переменную за пределами цикла.

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

Область видимости внутри функции

Поведение переменных, декларированных внутри функции при помощи ключевых слов var и let, одинаковое. В обоих случаях у переменных будет локальная область видимости.

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

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

Глобальные переменные в HTML

В JavaScript глобальная область видимости распространяется на все окружение JavaScript.

В HTML глобальная область видимости — это глобальный объект window.

Глобальные переменные, декларированные при помощи ключевого слова var, принадлежат глобальному объекту window:

Глобальные переменные, декларированные при помощи ключевого слова let, не принадлежат глобальному объекту window:

Передекларирование

Передекларировать переменную JavaScript при помощи ключевого слова var можно в любом месте программы:

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

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

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

Передекларировать переменную при помощи ключевого слова let в другой области видимости или в другом блоке можно:

Поднятие

Переменные, декларированные при помощи ключевого слова var, «поднимаются» в верх JavaScript кода (если вы не знаете, что такое «поднятие» в JavaScript, то см. главу Поднятие переменных в Javascript).

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

Переменные, декларированные при помощи ключевого слова let, не «поднимаются» в верх JavaScript кода.

Использование переменной, декларированной при помощи ключевого слова let, до ее реальной декларации приведет к ошибке ReferenceError.

В этом случае такая переменная находится в, так называемой, «временной мертвой зоне» с начала блока и до ее декларации:

Источник

Использование let объявлений переменных и особенности образуемых связываний в замыканиях в JavaScript

Написать данную заметку меня сподвигло прочтение статьи на Хабре «Var, let или const? Проблемы областей видимости переменных и ES6» и комментариев к ней, а также соответствующей части книги Закаса Н. «Understanding of ECMAScript 6». Исходя из прочитанного я вынес, что не всё так однозначно в оценке использования var или let. Авторы и комментаторы склоняются к тому, что при отсутствии необходимости поддержки старых версий браузеров имеет смысл полностью отказаться от использования var, а также использовать некоторые упрощенные конструкции, заместо старых, по умолчанию.

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

Для начала хотелось бы рассмотреть выражения немедленно вызываемых функций (Immediately Invoked Function Expression, IIFE) в циклах.

или можно обойтись без них используя let:

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

«This loop works exactly like the loop that used var and an IIFE but is arguably cleaner»

что, впрочем, сам же, чуть далее, косвенно опровергает.

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

В данном конкретном случае, результат действительно не отличается, но, что если мы немного усложним код?

Здесь, добавив ++i наш результат оказался вполне предсказуем, так как мы вызвали функцию со значениями i, актуальными на момент вызова ещё при проходах самого цикла, поэтому последующая операция ++i не повлияла на значение переданное функции в массиве, так как оно было передано в замыкание с помощью вызова внешней function(i) и оказалось связанно с полученным ею аргументом.

Теперь сравним с let-варинтом без IIFE

Результат, как видно, изменился, и, природа этого изменения, в том, что значение используемое в замыкании теперь связано не с областью видимости охватывающей функции, как до этого, а с областью относящейся к конкретному проходу цикла for. И на момент вызова функции через оператор Array.prototype.forEach() в этой области значение i уже было увеличено на 1 следующей за добавлением функции в массив инструкцией ++i.

Чтобы глубже понять суть происходящего, рассмотрим примеры с двумя массивами. И для начала, возьмём var, без IIFE:

Здесь всё пока очевидно — замыканий нет, т. е., аналогичной, но с замыканием, будет подобная запись:

В обоих примерах происходит следующее:

1. В начале последней итерации цикла i == 2, затем инкрементируется на 1 (++i), и в конце добавляется еще 1 от i++, В результате на конец всего цикла i == 4.

2. Поочередно вызываются функции находящиеся в массивах func1 и func2, и в каждой из них последовательно инкрементируется одна и та же переменная i, захваченная по ссылке ими обеими из внешней области видимости (глобальной в первом варианте и function test() во втором).

Добавим IIFE.
Первый вариант:Второй вариант:
При добавлении IIFE в первом случае мы вызвали зафиксированные значения i из области видимости function(i) (0 и 2, при первом и втором проходе цикла соответственно), и инкрементировали их на 1, каждая функция отдельно от другой, так как здесь нет захвата общей переменной, ввиду того, что значение i было переданно немедленно, как аргумент функции вернувшей замыкания, при соответствующих проходах цикла. Во втором случае общее связывание также отсутствует, но тут значение передается с одновременной инкременцией, поэтому на конец первого прохода i == 4, и, цикл дальше не пошёл. Но, обращаю внимание, на то, что в замыканиях связывания переменных всё также присутствуют как в первом так и втором вариантах. Например:
прим.: даже если обрамить цикл функцией, общими, связывания, естественно не станут, так как у каждой функции сейчас своя отдельная область видимости образованная вызовом вернувших их функций.

Теперь же рассмотрим инструкцию let, без IIFE соответственно.

А вот здесь, у нас образовались замыкания со связанными переменными цикла, и не отдельными, а общими.

В итоге мы имеем, что в первой области видимости, до вызова, значение i == 1, а во второй i == 3. Это значения, которые получила переменная i, до i++ в конце соответствующих итераций цикла, но после всех инструкций в блоке цикла.

Далее вызываются функции находящиеся в массиве func1 и они инкрементируют соответствующие переменные в обеих областях видимости и в результате в первой i == 2, а во второй i == 4.

Последующий вызов func2 инкрементирует те же переменные дальше и получает i == 3 и 5 соответственно.

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

Напоследок приведу тривиальный пример направленный на закрепление понимания замыканий и области видимости let :

Что мы имеем в итоге

1. Задействование выражений немедленно вызываемых функций не является эквивалентным использованию итерируемых let переменных в функциях в циклах, и, в ряде случаев, приводит к различному результату.

2. Из-за того, что при использовании let объявления для итератора в каждой итерации создаётся отдельная локальная переменная, встаёт вопрос об утилизации ненужных данных сборщиком мусора. На этом пункте, признаться, я и хотел изначально заострить внимание, подозревая, что создание большого количества переменных в больших, соответственно, циклах будет тормозить работу компилятора, однако, при сортировке тестового массива с использованием только let объявлений переменных показало выигрыш по времени выполнения почти в два раза для массива в 100000 ячеек (по данной теме есть отдельная статья – см. ниже ссылку в комментарии – и там поясняется, что рассмотренный тест и его результаты имеют специфическую природу):

При этом время выполнения практически не зависело от наличия/отсутствия инструкций:

Источник

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

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

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

В этой статье вы узнаете 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 не будет опубликован. Обязательные поля помечены *