- Переменные: let и const
- const
- Итого
- Javascript что значит let
- Правила области видимости
- Чище код во вложенных функциях
- Эмуляция приватных членов
- Временные мёртвые зоны и ошибки при использовании let
- Использование let в циклах for
- Правила области видимости
- Примеры
- let vs var
- let в циклах
- Нестандартизированные расширения let
- let блок
- Синтаксис
- Описание
- Пример
- Правила области видимости
- let выражения
- Синтаксис
- Пример
- Правила области видимости
- В чём разница между var, let и const в JavaScript
- Инициализация и объявление переменной
- Область видимости
- Hoisting
- var VS let VS const
- let VS const
Переменные: let и const
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
В ES-2015 предусмотрены новые способы объявления переменных: через let и const вместо var .
У объявлений переменной через let есть три основных отличия от var :
Область видимости переменной let – блок <. >.
Как мы помним, переменная, объявленная через var , видна везде в функции.
Переменная, объявленная через let , видна только в рамках блока <. >, в котором объявлена.
Это, в частности, влияет на объявления внутри if , while или for .
Например, переменная через var :
В примере выше apples – одна переменная на весь код, которая модифицируется в if .
То же самое с let будет работать по-другому:
Здесь, фактически, две независимые переменные apples , одна – глобальная, вторая – в блоке if .
Заметим, что если объявление let apples в первой строке (*) удалить, то в последнем alert будет ошибка: переменная не определена:
Это потому что переменная let всегда видна именно в том блоке, где объявлена, и не более.
Переменная let видна только после объявления.
Как мы помним, переменные var существуют и до объявления. Они равны undefined :
С переменными let всё проще. До объявления их вообще нет.
Такой доступ приведёт к ошибке:
Заметим также, что переменные let нельзя повторно объявлять. То есть, такой код выведет ошибку:
Это – хоть и выглядит ограничением по сравнению с var , но на самом деле проблем не создаёт. Например, два таких цикла совсем не конфликтуют:
При объявлении внутри цикла переменная i будет видна только в блоке цикла. Она не видна снаружи, поэтому будет ошибка в последнем alert .
При использовании в цикле, для каждой итерации создаётся своя переменная.
Переменная var – одна на все итерации цикла и видна даже после цикла:
С переменной let – всё по-другому.
Каждому повторению цикла соответствует своя независимая переменная let . Если внутри цикла есть вложенные объявления функций, то в замыкании каждой будет та переменная, которая была при соответствующей итерации.
Это позволяет легко решить классическую проблему с замыканиями, описанную в задаче Армия функций.
Если бы объявление было var i , то была бы одна переменная i на всю функцию, и вызовы в последних строках выводили бы 10 (подробнее – см. задачу Армия функций).
А выше объявление let i создаёт для каждого повторения блока в цикле свою переменную, которую функция и получает из замыкания в последних строках.
const
Объявление const задаёт константу, то есть переменную, которую нельзя менять:
В остальном объявление const полностью аналогично let .
Заметим, что если в константу присвоен объект, то от изменения защищена сама константа, но не свойства внутри неё:
То же самое верно, если константе присвоен массив или другое объектное значение.
Константы, которые жёстко заданы всегда, во время всей программы, обычно пишутся в верхнем регистре. Например: const ORANGE = «#ffa500» .
Большинство переменных – константы в другом смысле: они не меняются после присвоения. Но при разных запусках функции это значение может быть разным. Для таких переменных можно использовать const и обычные строчные буквы в имени.
Итого
- Видны только после объявления и только в текущем блоке.
- Нельзя переобъявлять (в том же блоке).
- При объявлении переменной в цикле for(let …) – она видна только в этом цикле. Причём каждой итерации соответствует своя переменная let .
Переменная const – это константа, в остальном – как let .
Источник
Javascript что значит let
Директива let позволяет объявить локальную переменную с областью видимости, ограниченной текущим блоком кода . В отличие от ключевого слова var , которое объявляет переменную глобально или локально во всей функции, независимо от области блока.
Объяснение, почему было выбрано название «let» можно найти здесь.
Правила области видимости
Областью видимости переменных, объявленных ключевым словом let , является блок, в котором они объявлены, и все его подблоки. В этом работа директива let схожа с работой директивы var . Основная разница заключается в том, что областью видимости переменной, объявленной директивой var , является вся функция, в которой она объявлена:
Чище код во вложенных функциях
let иногда делает код чище при использовании вложенных функций.
Пример выше будет выполнен как и ожидается, так как пять экземпляров внутренней функции (анонимной) будут ссылаться на пять разных экземпляров переменной i . Пример будет выполнен неверно, если заменить директиву let на var, или удалить переменную i из параметров вложенной функции и использовать внешнюю переменную i во внутренней функции.
На верхнем уровне скриптов и функций let, в отличии от var, не создаёт свойства на глобальном объекте . Например:
В выводе программы будет отображено слово «global_x» для this.x , но undefined для this.y .
Эмуляция приватных членов
При взаимодействии с конструкторами можно использовать выражение let чтобы открыть доступ к одному или нескольким приватным членам через использование замыканий:
Эта техника позволяет получить только «статичное» приватное состояние — в примере выше, все экземпляры полученные из конструктора SomeConstructor будут ссылаться на одну и ту же область видимости privateScope .
Временные мёртвые зоны и ошибки при использовании let
Повторное объявление той же переменной в том же блоке или функции приведёт к выбросу исключения SyntaxError.
В стандарте ECMAScript 2015 переменные, объявленные директивой let, переносятся в начало блока. Но если вы сошлётесь в блоке на переменную, до того как она объявлена директивой let, то это приведёт к выбросу исключения ReferenceError , потому что переменная находится во «временной мёртвой зоне» с начала блока и до места её объявления. (В отличии от переменной, объявленной через var , которая просто будет содержать значение undefined )
Вы можете столкнуться с ошибкой в операторах блока switch , так как он имеет только один подблок.
Использование let в циклах for
Вы можете использовать ключевое слово let для привязки переменных к локальной области видимости цикла for . Разница с использованием var в заголовке цикла for , заключается в том, что переменные объявленные var , будут видны во всей функции, в которой находится этот цикл.
Правила области видимости
В этом примере expr2 , expr3, statement заключены в неявный блок, который содержит блок локальных переменных, объявленных конструкцией let expr1 . Пример приведён выше.
Примеры
let vs var
Когда let используется внутри блока, то область видимости переменной ограничивается этим блоком. Напомним, что отличие заключается в том, что областью видимости переменных, объявленных директивой var, является вся функция, в которой они были объявлены.
let в циклах
Вы можете использовать ключевое слово let для привязки переменных к локальной области видимости цикла for , вместо того что бы использовать глобальные переменные (объявленные с помощью var ).
Нестандартизированные расширения let
let блок
Поддержка let блоков была убрана в Gecko 44 баг 1023609.
let блок предоставляет способ, ассоциировать значения с переменными внутри области видимости этого блока, без влияния на значения переменных с теми же именами вне этого блока.
Синтаксис
Описание
let блок предоставляет локальную область видимости для переменных. Работа его заключается в привязке нуля или более переменных к области видимости этого блока кода, другими словами, он является блоком операторов. Отметим, что область видимости переменных, объявленных директивой var , в блоке let , будет той же самой, что и если бы эти переменные были объявлены вне блока let , иными словами областью видимости таких переменных по-прежнему является функция. Скобки в блоке let являются обязательными. Опускание их приведёт к синтаксической ошибке.
Пример
Правила для этого блока кода аналогичны как и для любого другого блока кода в JavaScript. Он может содержать свои локальные переменные, объявленные let .
Правила области видимости
Областью видимости переменных, объявленных директивой let , в блоке let является сам блок и все подблоки в нем, если они не содержат объявлений переменных с теми же именами.
let выражения
Поддержка let выражений была убрана в Gecko 41 баг 1023609.
let выражение позволяет объявить переменные с областью видимости ограниченной одним выражением.
Синтаксис
Пример
Вы можете использовать let для объявления переменных, областью видимости которых является только одно выражение:
Правила области видимости
В данном let выражении:
expr оборачивается в неявный блок.
Источник
В чём разница между var, let и const в JavaScript
Mar 19, 2019 · 7 min read
Сегодня вы узнаете два новых способа создавать переменные в JavaScript (ES6), а именно с помощью let и const . Мы разберёмся в чём разница между операторами var , let , и const . Ещё мы затронем такие темы, как: область видимости функции и блока, поднятие переменной (hoisting) и неизменность.
В спецификации ES2015 (ES6) нам представили два новых оператора для создания переменных: let и const . Чтобы понять различия между var , let , и const , мы должны сперва поговорить о таких понятиях, как: объявление и инициализация переменных, область видимости (особенно функции) и поднятие переменной.
Инициализация и объявление переменной
Объявление переменной вводит новый идентификатор.
Только ч т о мы создали новый идентификатор с именем declaration. Когда в JavaScript создаётся переменная, она инициализируется со значением undefined . Если мы сейчас попытаемся логировать переменную declaration , то нам вернётся undefined .
Инициализация — это присваивание значения переменной.
Итак, мы инициализировали переменную declaration , присвоив ей строку.
Это подводит нас к понятию «область видимости».
Область видимости
Область видимости определяет, где в коде программы будут доступны переменные и функции. В JavaScript есть два типа области видимости — глобальная и локальная ( global scope и function scope). Согласно официальной спецификации:
Если переменная создаётся внутри объявления функции, то её область видимости определяется как локальная и ограничивается этой функцией.
То есть, если вы создаёте переменную внутри функции с оператором var , то она будет доступна только внутри этой функции и вложенных в неё функциях.
В коде выше, мы пытаемся получить доступ к переменной вне функции, в которой она была объявлена. Так как переменная date ограничена областью видимости функции getDate , она доступна только внутри getDate или для любой вложенной в неё функции (как в примере ниже).
Давайте рассмотрим более сложный пример. Допустим у нас есть массивы prices и discount , нам нужно создать функцию, которая возьмёт значения из обоих массивов и вернёт новый массив цен с учётом скидок. В итоге у нас должен получится такой массив:
Выглядит довольно просто, но что происходит в области видимости блока? Обратите внимание на цикл for . Доступны ли переменные, которые объявлены внутри цикла, вне его? Оказывается, что да.
Если JavaScript это единственный язык программирования, которым вы владеете, то вы не заметите ничего странного. Но если вы перешли с другого языка, вы, вероятно, немного запутались в том, что здесь происходит.
Здесь нет ошибки, это просто немного необычно. К тому же, у нас нет необходимости иметь доступ к i , discountedPrice , и finalPrice вне цикла for . Для нас в этом нет никакой пользы, более того, в некоторых случаях это может мешать. Тем не менее, поскольку переменные, объявлены оператором var , они относятся к функции и доступны вне цикла.
Теперь вы знаете, что такое область видимости, инициализация и объявление переменных; нам осталось разобраться с понятием «поднятие переменной» (hoisting), прежде чем перейти к let и const .
Hoisting
Ранее я уже говорил, что при создании переменной в JavaScript, она инициализируются со значением undefined . Это и есть «Hoisting». Интерпретатор JavaScript присваивает переменой значение undefined по умолчанию, во время так называемой фазы «Создания».
Давайте посмотрим, как действует hoisting, на предыдущем примере:
Обратите внимание, что всем объявленным переменным присвоено значение undefined по умолчанию. Вот почему, если вы попытаетесь получить доступ к одной из этих переменных до того, как она была фактически объявлена, вам вернётся undefined .
Теперь, когда вы знаете о var всё что нужно, давайте наконец разберёмся в чём разница между var , let , и const ?
var VS let VS const
Сперва сравним var и let . Главное отличие let в том, что область видимости переменной ограничивается блоком, а не функцией. Другими словами, переменная, созданная с помощью оператора let , доступна внутри блока, в котором она была создана и в любом вложенном блоке. Говоря «блок», я имею ввиду всё что вложено между фигурными скобками <> , как например в цикле for или условии if .
Давайте в последний раз вернёмся к нашей функции discountPrices .
Помните, что мы можем логировать i , discountedPrice , и finalPrice вне цикла for , так как они созданы с помощью var , а значит видны в пределах функции. Но, что, если мы заменим оператор var на let и попробуем выполнить код.
Вот что мы получим: ReferenceError: i is not defined . Это подтверждает, что let переменные ограничены блоком, а не функцией. Поэтому попытка получить к ним доступ приводит к ошибке.
Следующее отличие связано с поднятием переменной. Ранее мы определили, что интерпретатор в JavaScript присваивает переменным значение undefined по умолчанию во время фазы «Создания». Вы даже видели это в действии, логируя переменную до её объявления (и получили undefined ).
Я даже не могу придумать причину, по которой стоит запрашивать переменную до её объявления. Мне кажется, что получать по умолчанию ReferenceError лучше, чем возврат undefined .
Кстати, именно это и делает let , т.е. вы получите ошибку ReferenceError вместо значения undefined , если запросите переменную, созданную оператором let , до её объявления.
let VS const
Различия между var и let мы выяснили, а что насчёт const ? Получается, что const и let почти одно и тоже. И всё же есть одно отличие: значение переменной, объявленной с помощью const , нельзя переназначить. Это можно увидеть в примере ниже:
Итак, если вы хотите, чтобы переменная была неизменной, используйте const . Ну, почти. На самом деле оператор const не делает переменную неизменной, а только не даёт переназначать её значение. Вот хороший пример:
Обратите внимание, что изменение свойства объекта не является его переназначением, поэтому, даже если объект объявлен с помощью const , это не означает, что вы не можете изменить ни одно из его свойств. Это только означает, что вы не можете переназначить его на новое значение.
Теперь главный вопрос: что следует использовать var , let , или const ? Наиболее популярное мнение, под которым подписываюсь и я, — всегда использовать const , кроме тех случаев, когда вы знаете, что переменная будет изменятся. Используя const , вы как бы говорите себе будущему и другим разработчикам, которые будут читать ваш код, что эту переменную изменять не следует. Если вам нужна изменяемая переменная (например, в цикле for ), то используйте let .
Таким образом, между изменяемыми и неизменяемыми переменными осталось не так много различий. Это означает, что вам больше не придётся использовать var .
Теперь «непопулярное» мнение, хотя оно и обоснованно (пока): вы никогда не должны использовать const, потому что, хотя вы пытаетесь показать, что переменная неизменна, это не совсем правда (мы видели это на примере выше). Разработчики, которые разделяют это мнение, всегда используют let , за исключением случаев когда переменная действительно является константой, например _LOCATION_ = . .
Повторим для закрепления. Область видимости var переменных ограничена функцией, если вы обратитесь к переменной до её объявления, то получите undefined . const и let ограничены блоком, а попытка обратится к переменной до её объявления, вернётся ошибкой ReferenceError. И наконец, разница между let и const в том, что в первом случае вы можете изменить значение переменной, а во втором нет.
Источник