ECMAScript 6 представил это let
заявление .
Я слышал, что она описывается как «локальная» переменная, но я все еще не совсем уверен, как она ведет себя иначе, чем var
ключевое слово.
В чем различия? Когда следует let
использовать более var
?
ECMAScript 6 представил это let
заявление .
Я слышал, что она описывается как «локальная» переменная, но я все еще не совсем уверен, как она ведет себя иначе, чем var
ключевое слово.
В чем различия? Когда следует let
использовать более var
?
let
включен в черновик 6-го издания и, скорее всего, будет в окончательной спецификации.Ответы:
Общие правила
Основное отличие заключается в правилах определения объема. Переменные, объявленные
var
ключевым словом, попадают в область непосредственного тела функции (отсюда область действия функции), аlet
переменные - в непосредственный включающий блок, обозначенный{ }
(отсюда область действия блока).Причина, по которой
let
ключевое слово было введено в язык, заключалась в том, что область действия функций сбивает с толку и является одним из основных источников ошибок в JavaScript.Взгляните на этот пример из другого вопроса stackoverflow :
My value: 3
выводился на консоль каждый разfuncs[j]();
вызывался, поскольку анонимные функции были связаны с одной и той же переменной.Люди должны были создавать немедленно вызываемые функции для получения правильных значений из циклов, но это также было проблематично.
Подъемно
В то время как переменные, объявленные с
var
ключевым словом, поднимаются (инициализируются с помощьюundefined
до запуска кода), что означает, что они доступны в пределах их охвата даже до того, как они объявлены:let
переменные не инициализируются до тех пор, пока их определение не будет оценено. Доступ к ним до инициализации приводит кReferenceError
. Считается, что переменная находится в «временной мертвой зоне» от начала блока до обработки инициализации.Создание глобального свойства объекта
На верхнем уровне, в
let
отличиеvar
, не создается свойство глобального объекта:переопределение
В строгом режиме
var
позволит вам повторно объявить одну и ту же переменную в той же области, в то времяlet
как выдает ошибку SyntaxError.источник
let
Выражение блока неlet (variable declaration) statement
является стандартным и будет удалено в будущем, bugzilla.mozilla.org/show_bug.cgi?id=1023609 .let
может также использоваться, чтобы избежать проблем с закрытием. Он связывает свежую ценность, а не сохраняет старую ссылку, как показано в примерах ниже.Код выше демонстрирует классическую проблему закрытия JavaScript. Ссылка на
i
переменную сохраняется в закрытии обработчика щелчка, а не на фактическое значениеi
.Каждый обработчик одного клика будет ссылаться на один и тот же объект, потому что есть только один встречный объект, который содержит 6, поэтому вы получаете шесть на каждый клик.
Общий обходной путь - обернуть это в анонимную функцию и передать
i
в качестве аргумента. Таких проблем можно также избежать, используяlet
вместо этого,var
как показано в коде ниже.(Проверено в Chrome и Firefox 50)
источник
let
, но предупреждает «6» для всех кнопок. Есть ли у вас источник, говорящий, какlet
должен вести себя?let
было бы действительно полезно. Установка прослушивателей событий в цикле больше не требует немедленного вызова выражения функции для локальной видимостиi
на каждой итерации.Какая разница между
let
аvar
?var
оператора, известна во всей функции, в которой она определена, с самого начала функции. (*)let
оператора, известна только в том блоке, в котором она определена, с момента ее определения. (**)Чтобы понять разницу, рассмотрим следующий код:
Здесь мы видим, что наша переменная
j
известна только в первом цикле for, но не до и после. Тем не менее, наша переменнаяi
известна во всей функции.Кроме того, учтите, что переменные в области блока не известны до того, как они объявлены, потому что они не подняты. Вам также не разрешается повторно объявлять одну и ту же переменную области действия блока в одном и том же блоке. Это делает переменные области блока менее подверженными ошибкам, чем переменные глобальной или функциональной области, которые перемещаются и которые не выдают никаких ошибок в случае нескольких объявлений.
Безопасно ли использовать
let
сегодня?Некоторые люди утверждают, что в будущем мы будем использовать ТОЛЬКО операторы let, а операторы var станут устаревшими. JavaScript гуру Кайл Симпсон написал очень сложную статью о том, почему он считает, что это не так .
Сегодня, однако, это определенно не так. На самом деле, нам нужно спросить себя, безопасно ли использовать это
let
утверждение. Ответ на этот вопрос зависит от вашей среды:Если вы пишете код JavaScript на стороне сервера ( Node.js ), вы можете смело использовать это
let
утверждение.Если вы пишете код JavaScript на стороне клиента и используете браузер (например, Traceur или babel-standalone ), вы можете смело использовать это
let
утверждение, однако ваш код, вероятно, будет не оптимальным с точки зрения производительности.Если вы пишете код JavaScript на стороне клиента и используете транспортер на основе Node (например, скрипт оболочки traceur или Babel ), вы можете смело использовать это
let
утверждение. А поскольку ваш браузер будет знать только о передаваемом коде, недостатки производительности должны быть ограничены.Если вы пишете код JavaScript на стороне клиента и не используете транспортер, вам следует подумать о поддержке браузера.
Есть еще некоторые браузеры, которые вообще не поддерживают
let
:Как отслеживать поддержку браузера
Обновленный обзор того, какие браузеры поддерживают
let
оператор на момент прочтения этого ответа, см. На этойCan I Use
странице .(*) Глобальные и функциональные переменные могут быть инициализированы и использованы до того, как объявлены, потому что переменные JavaScript подняты .Это означает, что объявления всегда находятся на вершине области видимости.
(**) Переменные области видимости не подняты
источник
i
IS известен везде в функциональном блоке! Он начинается какundefined
(из-за подъема), пока вы не назначите значение! ps:let
также поднимается (до верхней части содержащего его блока), но будет даватьReferenceError
ссылку, когда на него ссылаются в блоке перед первым присваиванием. (ps2: я парень вроде точки с запятой, но вам не нужна точка с запятой после блока). При этом, спасибо за добавление проверки реальности в отношении поддержки!let
иvar
!let
иconst
его рекомендовали использовать только тогда, когда вам действительно нужны их дополнительные функции , потому что принудительное выполнение / проверка этих дополнительных функций (таких как const только для записи) приводит к «большему количеству работы». '(и дополнительные узлы области видимости в дереве областей действия) для (текущего) механизма (ов) для принудительного применения / проверки / проверки / настройки.Вот объяснение
let
ключевого слова с некоторыми примерами.Этот стол в Википедии показывает, какие браузеры поддерживают Javascript 1.7.
Обратите внимание, что только браузеры Mozilla и Chrome поддерживают его. IE, Safari и, возможно, другие не делают.
источник
let
msdn.microsoft.com/en-us/library/ie/dn342892%28v=vs.85%29.aspxВ принятом ответе отсутствует точка:
источник
for
инициализаторе цикла, резко сузив сферу применения ограниченийlet
. Upvoted.let
Блок область
Переменные, объявленные с использованием
let
ключевого слова, имеют вид блока, что означает, что они доступны только в блоке. в котором они были объявлены.На верхнем уровне (вне функции)
На верхнем уровне переменные, объявленные с использованием
let
, не создают свойств для глобального объекта.Внутри функции
Внутри функции (но вне блока)
let
имеет такую же область, какvar
.Внутри блока
Переменные, объявленные с использованием
let
внутри блока, не могут быть доступны вне этого блока.Внутри петли
На переменные, объявленные
let
в циклах in, можно ссылаться только внутри этого цикла.Петли с крышками
Если вы используете
let
вместоvar
цикла, с каждой итерацией вы получите новую переменную. Это означает, что вы можете безопасно использовать замыкание внутри цикла.Временная мертвая зона
Из-за временной мертвой зоны переменные, объявленные с использованием,
let
не могут быть доступны до их объявления. Попытка сделать это выдает ошибку.Нет повторного объявления
Вы не можете объявить одну и ту же переменную несколько раз, используя
let
. Вы также не можете объявить переменную, используяlet
тот же идентификатор, что и другая переменная, которая была объявлена с помощьюvar
.const
const
очень похож наlet
блок-область и имеет TDZ. Однако есть две разные вещи.Нет переназначения
Переменная, объявленная с использованием,
const
не может быть переназначена.Обратите внимание, что это не означает, что значение является неизменным. Его свойства еще можно изменить.
Если вы хотите иметь неизменный объект, вы должны использовать
Object.freeze()
.Требуется инициализатор
Вы всегда должны указывать значение при объявлении переменной с помощью
const
.источник
Вот пример различия между этими двумя (поддержка только началась для Chrome):
Как вы можете видеть,
var j
переменная все еще имеет значение за пределами области действия цикла for (Block Scope), ноlet i
переменная не определена вне области действия цикла for.источник
Есть некоторые тонкие различия - область
let
видимости ведет себя больше как переменная область видимости в более или менее любых других языках.Например, он распространяется на вмещающий блок, они не существуют до их объявления и т. д.
Однако стоит отметить, что
let
это только часть более новых реализаций Javascript и имеет различную степень поддержки браузера .источник
let
включен в черновик 6-го издания и, скорее всего, будет в окончательной спецификации.let
. Safari, IE и Chome - нет.let
не поднимайте, чтобы использовать переменную,let
определенную в верхней части вашего блока. Если у вас естьif
утверждение, которое состоит из нескольких строк кода, вы можете забыть, что не можете использовать эту переменную до тех пор, пока она не будет определена. БОЛЬШАЯ ТОЧКА !!!let
будет поднята переменная в верхнюю часть блока. Однако ссылка на переменную в блоке до объявления переменной приводит к ReferenceError (мое примечание: вместо старого доброгоundefined
). переменная находится в «временной мертвой зоне» от начала блока до обработки объявления. " То же самое касается «операторов переключения, потому что есть только один базовый блок». Источник: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Основное отличие является сфера разницы, в то время как пусть может быть доступны только внутри сферы он объявлен, как в течение цикла, вар может быть доступен за пределами цикла, например. Из документации в MDN (примеры также из MDN):
Также не забывайте, что это функция ECMA6, поэтому она еще не полностью поддерживается, поэтому лучше всегда переносить ее на ECMA5 с помощью Babel и т. Д. ... для получения дополнительной информации о посещении веб-сайта babel
источник
Переменная не поднимаетсяlet
не будет подниматься на весь объем блока, в котором они появляются. В отличие от этого,var
может подниматься, как показано ниже.Собственно, Per @Bergi, оба
var
иlet
подняты .Вывоз мусора
let
Полезный блок блока относится к замыканиям и сборке мусора для восстановления памяти. Рассматривать,click
Обратный вызов обработчика не нуждается вhugeData
переменном вообще. Теоретически, послеprocess(..)
прогонов огромная структура данныхhugeData
может быть собрана мусором. Тем не менее, возможно, что какой-то движок JS все равно должен будет сохранить эту огромную структуру, так какclick
функция имеет замыкание по всей области видимости.Тем не менее, область действия блока может превратить эту огромную структуру данных в сборщик мусора.
let
петлиlet
в цикле можно повторно привязать его к каждой итерации цикла, убедившись, что заново присвоить ему значение с конца предыдущей итерации цикла. Рассматривать,Однако заменить
var
наlet
Поскольку
let
создайте новую лексическую среду с этими именами для a) выражения инициализатора b) каждой итерации (прежде всего для вычисления выражения приращения), здесь есть больше деталей .источник
Вот пример, чтобы добавить к тому, что уже написали другие. Предположим, вы хотите создать массив функций,
adderFunctions
где каждая функция принимает один аргумент Number и возвращает сумму аргумента и индекс функции в массиве. Попытка созданияadderFunctions
цикла с использованиемvar
ключевого слова не будет работать так, как кто-то может наивно ожидать:Вышеописанный процесс не генерирует желаемый массив функций, поскольку
i
область действия выходит за рамки итерацииfor
блока, в котором была создана каждая функция. Вместо этого в конце циклаi
закрытие в каждой функции ссылается наi
значение в конце цикла (1000) для каждой анонимной функции вadderFunctions
. Это совсем не то, что мы хотели: у нас теперь есть массив из 1000 различных функций в памяти с точно таким же поведением. И если мы впоследствии обновим значениеi
, мутация повлияет на всеadderFunctions
.Однако мы можем повторить попытку, используя
let
ключевое слово:На этот раз
i
отскок на каждой итерацииfor
цикла. Каждая функция теперь сохраняет значениеi
на момент ее создания иadderFunctions
ведет себя как ожидалось.Теперь смешайте два поведения, и вы, вероятно, поймете, почему не рекомендуется смешивать новое
let
иconst
старшееvar
в одном и том же сценарии. Это может привести к некоторому удивительно запутанному коду.Не позволяй этому случиться с тобой. Используйте линтер.
источник
let value = i;
.for
Оператор создает лексический блок.Разница заключается в объеме переменных, объявленных с каждой.
На практике существует ряд полезных последствий разницы в области применения:
let
переменные видны только в ближайшем окружающем их блоке ({ ... }
).let
переменные можно использовать только в строках кода, которые появляются после объявления переменной (даже если они подняты !).let
переменные не могут быть повторно объявлены последующимvar
илиlet
.let
переменные не добавляются в глобальныйwindow
объект.let
Переменные легко использовать с замыканиями (они не вызывают условий гонки ).Ограничения, налагаемые посредством,
let
уменьшают видимость переменных и увеличивают вероятность того, что неожиданные конфликты имен будут обнаружены рано. Это облегчает отслеживание и рассуждение о переменных, включая их достижимость (помогая восстановить неиспользуемую память).Следовательно,
let
переменные с меньшей вероятностью вызывают проблемы при использовании в больших программах или когда независимо разработанные структуры объединяются новыми и неожиданными способами.var
может по-прежнему быть полезным, если вы уверены, что хотите использовать эффект одиночного связывания при использовании замыкания в цикле (# 5) или для объявления внешне видимых глобальных переменных в вашем коде (# 4). Использованиеvar
для экспорта может быть вытеснено, еслиexport
мигрирует из пространства транспортера в основной язык.Примеры
1. Не использовать вне ближайшего окружающего блока: этот блок кода выдаст опорную ошибку, потому что второе использование
x
происходит за пределами блока, где оно объявлено с помощьюlet
:Напротив, тот же пример с
var
работами.2. Не использовать перед объявлением:
этот блок кода будет бросать
ReferenceError
перед запуском кода, потому чтоx
используется до того, как он объявлен:Напротив, тот же пример с
var
анализами и запусками без каких-либо исключений.3. Без повторного объявления: следующий код демонстрирует, что объявленная переменная
let
не может быть повторно объявлена позже:4. Глобалы, не привязанные к
window
:5. Простота использования с замыканиями: переменные, объявленные с помощью
var
, плохо работают с замыканиями внутри циклов. Вот простой цикл, который выводит последовательность значений переменнойi
в разные моменты времени:В частности, это выводит:
В JavaScript мы часто используем переменные значительно позже, чем когда они создаются. Когда мы продемонстрируем это путем задержки вывода с закрытием, переданным
setTimeout
:... вывод остается неизменным, пока мы придерживаемся
let
. Напротив, если бы мы использовалиvar i
вместо:... цикл неожиданно выдает "i is 5" пять раз:
источник
var
вместоlet
кода эквивалентно:var i = 0; while (i < 5) { doSomethingLater(); i++; }
i
находится за пределами замыкания и к моментуdoSomethingLater()
выполненияi
уже увеличено в 5 раз, следовательно, выходной результат будет вi is 5
пять раз. Используяlet
, переменнаяi
находится в замыкании, поэтому каждый асинхронный вызов получает свою собственную копиюi
вместо использования «глобальной» копии , созданной с помощьюvar
.for
. Более точным преобразованием, хотя и более сложным, является классическоеfor (var i = 0; i < 5; i++) { (function(j) { setTimeout(_ => console.log(
i is $ {j},), 125/*ms*/); })(i); }
которое вводит «запись активации функции» для сохранения каждого значенияi
с именемj
внутри функции.Пусть следующие две функции показывают разницу:
источник
let
это интересно, потому что это позволяет нам делать что-то вроде этого:Что приводит к подсчету [0, 7].
В то время как
Считает только [0, 1].
источник
Область действия функции VS:
Основное различие между
var
иlet
заключается в том, что переменные, объявленные с помощью,var
являются областью видимости функции . Принимая во внимание, что функции, объявленные с,let
являются областью действия блока . Например:переменные с
var
:Когда первая функция вызывается,
testVar
переменная foo, объявленная с помощьюvar
, все еще доступна внеif
оператора. Эта переменнаяfoo
будет доступна везде в пределахtestVar
функции .переменные с
let
:Когда вторая функция вызывается,
testLet
переменная bar, объявленная с помощьюlet
, становится доступной только внутриif
оператора. Поскольку переменные, объявленные с помощью,let
имеют область видимости блока (где блок - это код в фигурных скобках, напримерif{}
,for{}
,function{}
).let
переменные не поднимаются:Еще одно различие между
var
иlet
является переменными с объявленным сlet
не подниматься . Пример - лучший способ проиллюстрировать это поведение:переменные с
let
не поднимаются:переменные с
var
делать прибудут водрузил:Глобал
let
не привязывается кwindow
:Переменная, объявленная
let
в глобальной области видимости (то есть код, который отсутствует в функции), не добавляется в качестве свойства глобальногоwindow
объекта. Например (этот код находится в глобальной области видимости):Используйте
let
болееvar
когда вы можете, потому что это просто более определенная область. Это уменьшает потенциальные конфликты именования, которые могут возникнуть при работе с большим количеством переменных.var
может использоваться, когда вы хотите, чтобы глобальная переменная явно находилась наwindow
объекте (всегда тщательно продумывайте, действительно ли это необходимо).источник
Также кажется, что, по крайней мере, в Visual Studio 2015, TypeScript 1.5, «var» допускает несколько объявлений одного и того же имени переменной в блоке, а «let» - нет.
Это не сгенерирует ошибку компиляции:
Это будет:
источник
var
глобальная переменная области видимостиlet
иconst
является областью блока.источник
Когда используешь
let
let
Ключевое слово придает объявление переменного в рамки какого - либо блок (обычно является{ .. }
пара) он содержится. Другими словами,let
неявно угоняет объем любого блока для его объявления переменного.let
переменные не могут быть доступны вwindow
объекте, потому что они не могут быть доступны глобально.Когда используешь
var
var
а переменные в ES5 имеют области действия в функциях, что означает, что переменные действительны внутри функции, а не вне самой функции.var
переменные могут быть доступны вwindow
объекте, потому что они не могут быть доступны глобально.Если вы хотите узнать больше, продолжайте читать ниже
один из самых известных вопросов интервью по объему также может быть достаточным для точного использования
let
иvar
как показано ниже;Когда используешь
let
Это связано с тем, что при использовании
let
для каждой итерации цикла переменная находится в области видимости и имеет свою собственную копию.Когда используешь
var
Это связано с тем, что при использовании
var
для каждой итерации цикла переменная находится в области видимости и имеет общую копию.источник
В самых общих чертах,
⚡️ Песочница для игры ↓
источник
Если я читаю спецификации правильно, то, к
let
счастью, их также можно использовать, чтобы избежать самовозвратных функций, используемых для имитации закрытых элементов - популярного шаблона проектирования, который уменьшает читабельность кода, усложняет отладку, не добавляет никакой реальной защиты кода или других преимуществ - за исключением, возможно, удовлетворения чьего-либо желание семантики, так что прекратите его использовать. / напыщеннаяСмотрите « Эмуляция частных интерфейсов ».
источник
let
делают? (Я предполагаю, что вы имеете в виду IIFE с «функцией самовозбуждения».)hiddenProperty
в конструкторе? ВhiddenProperty
вашем «классе» есть только один экземпляр.Некоторые хаки с
let
:1.
2.
3.
Получатель и установщик с
let
:источник
let { type, name, value } = node;
? Вы создаете новый объект с 3 свойствами тип / имя / значение и инициализируете их значениями свойств из узла?var
.пусть является частью es6. Эти функции объяснят разницу простым способом.
источник
пусть против вар. Все дело в сфере .
Переменные var глобальны и доступны практически везде, а переменные пусть не глобальны и существуют только до тех пор, пока закрывающая скобка не убьет их.
Посмотрите мой пример ниже и обратите внимание, как переменная lion (let) действует по-разному в двух console.logs; это выходит из области видимости во втором console.log.
источник
источник
Ниже показано, как «let» и «var» различаются по объему:
Определение
gfoo
, определенноеlet
изначально, находится в глобальной области видимости , и когда мыgfoo
снова объявляем внутри областиif clause
его изменения, и когда переменная внутри этой области присваивается новое значение, это не влияет на глобальную область действия.Принимая во внимание
hfoo
, что определение, определенноеvar
изначально, находится в глобальной области видимости , но, опять же, когда мы объявляем его внутриif clause
, оно рассматривает глобальную область действия hfoo, хотя var снова использовался для его объявления. И когда мы переназначаем его значение, мы видим, что глобальная область действия hfoo также затронута. Это основное отличие.источник
Как указано выше:
Example1:
В обоих моих примерах у меня есть функция
myfunc
.myfunc
содержит переменную,myvar
равную 10. В моем первом примере я проверяю,myvar
равно ли равно 10 (myvar==10
). Если да, я объявляю переменнуюmyvar
(теперь у меня есть две переменные myvar), используяvar
ключевое слово, и присваиваю ей новое значение (20). В следующей строке я печатаю его значение на моей консоли. После условного блока я снова печатаю значениеmyvar
на моей консоли. Если вы посмотрите на выводmyfunc
,myvar
имеет значение, равное 20.Пример 2: Во втором примере вместо использования
var
ключевого слова в моем условном блоке я объявляюmyvar
использованиеlet
ключевого слова. Теперь, когда я звоню,myfunc
я получаю два разных выхода:myvar=20
иmyvar=10
.Таким образом, разница очень проста, т.е.
источник
Я хочу связать эти ключевые слова с контекстом выполнения, потому что контекст выполнения важен во всем этом. Контекст выполнения имеет две фазы: фаза создания и фаза выполнения. Кроме того, каждый контекст выполнения имеет переменную среду и внешнюю среду (свою лексическую среду).
На этапе создания контекста выполнения var, let и const будут по-прежнему сохранять свою переменную в памяти с неопределенным значением в среде переменных данного контекста выполнения. Разница заключается в фазе исполнения. Если вы используете ссылку на переменную, определенную с помощью var, до того, как ей будет присвоено значение, она будет просто неопределенной. Никаких исключений не будет.
Однако вы не можете ссылаться на переменную, объявленную с помощью let или const, пока она не будет объявлена. Если вы попытаетесь использовать его до того, как он будет объявлен, тогда будет возникать исключительная ситуация на этапе выполнения контекста выполнения. Теперь переменная все еще будет в памяти, благодаря фазе создания контекста выполнения, но механизм не позволит вам использовать ее:
С переменной, определенной с помощью var, если Engine не может найти переменную в переменной среде текущего контекста выполнения, он поднимется по цепочке областей действия (внешняя среда) и проверит переменную среду внешней среды для переменной. Если он не может найти его там, он продолжит поиск в Scope Chain. Это не относится к let и const.
Вторая особенность let - это введение в область видимости блока. Блоки определяются фигурными скобками. Примеры включают в себя функциональные блоки, блоки if, для блоков и т. Д. Когда вы объявляете переменную с помощью let inside блока, переменная доступна только внутри блока. Фактически, каждый раз, когда блок запускается, например, в цикле for, он создает новую переменную в памяти.
ES6 также вводит ключевое слово const для объявления переменных. const также имеет ограниченную область видимости. Разница между let и const заключается в том, что переменные const должны быть объявлены с использованием инициализатора, иначе это вызовет ошибку.
И, наконец, когда дело доходит до контекста выполнения, переменные, определенные с помощью var, будут присоединены к объекту 'this'. В глобальном контексте выполнения это будет объект окна в браузерах. Это не относится к let или const.
источник
Я думаю, что термины и большинство примеров немного ошеломляют. Основная проблема, с которой я столкнулся лично, - это понимание, что такое «Блок». В какой-то момент я понял, что блоком будут любые фигурные скобки, кроме
IF
оператора. открывающая скобка{
функции или цикла будет определять новый блок, все, что определеноlet
внутри него, не будет доступно после закрывающей скобки}
того же самого элемента (функции или цикла); Имея это в виду, было легче понять:источник
Теперь я думаю, что есть лучшая область видимости переменных для блока операторов, использующего
let
:Я думаю, что люди начнут использовать let here после этого, чтобы у них была такая же область видимости в JavaScript, как и в других языках, Java, C # и т. Д.
Люди с неясным пониманием области видимости в JavaScript раньше делали ошибку.
Подъем не поддерживается с помощью
let
.При таком подходе ошибки, присутствующие в JavaScript, удаляются.
Обратитесь к ES6 In Depth: пусть и const, чтобы понять это лучше.
источник
Эта статья четко определяет разницу между var, let и const
https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.esmkpbg9b
источник