Очень долго в JavaScript объявление переменных выполнялось с помощью ключевого слова var
. В стандарте EcmaScript 2015 (который чаще называют ES6) к нему добавилось еще 2 ключевых слова: let
- для объявления переменных с ограниченной областью видимости и const
- для объявления констант, т.е. переменных с неизменяемым значением.
Если вы объявляете переменную с помощью let
в начале скрипта, то большого отличия от var
вы не заметите. Но ситуация меняется, когда объявленная таким образом переменная появляется в цикле или в условной конструкции типа if...else
внутри фигурных скобок. Даже просто при использовании фигурных скобок область видимости переменной, объявленной с помощью let
, ограничивается исключительно областью этих скобок, т.е. блоком кода.
В примере ниже мы используем 2 разных объявления переменной a
. До и после скобок она имеет значение, присвоенное ей с помощью ключевого слова var
, а внутри скобок - значение, присвоенное с помощью ключевого слова let
.
1 2 3 4 5 6 7 |
var a = 5; document.write("<p>Объявление <strong>var</strong> a="+a+"</p>"); { let a = 10; document.write("<p>Объявление <strong>let</strong> a="+a+"</p>"); } document.write("<p>После скобок <strong>a</strong>="+a+"</p>"); |
То есть переменная a
, заданная внутри скобок с помощью ключевого слова let
, не видна за пределами этих скобок. Таким образом раньше работали переменные, объявленные внутри функций, т.е. с локальной областью видимости.
Сравним с аналогичным скриптом в формате ES5:
1 2 3 4 5 6 7 |
var a = 5; document.write("<p>Объявление <strong>var</strong> a = "+a+"</p>"); { var a = 10; document.write("<p>Внутри скобок <strong>var</strong> a = "+a+"</p>"); } document.write("<p>После скобок <strong>a</strong> = "+a+"</p>"); |
Здесь мы получаем, что переопределение переменной a
внутри скобок сказалось на ее значении и после них, т.е. переопределение было в глобальной области видимости.
Следует еще отметить, что разница между var
и let
состоит в том, что с var
переменную можно объявить в любом месте - ее использование будет корректным, т.к. при загрузке скрипта интерпретатор находит все переменные, объявленные с помощью var
и запоминает их. Если вы попытаетесь вывести значение переменной, объявленной с помощью var
ДО ее объявления, то увидите undefined
. С let
такой номер не проходит. Сначала нужно объявить переменную, и только после этого - использовать ее, иначе вы получите очередное сообщение об ошибке.
1 2 3 4 5 6 7 8 9 |
<script> document.write("<p>Значение <strong>var b </strong> ДО объявления = "+b+"</p>"); var b = 125; document.write("<p>Значение <strong>var b </strong> ПОСЛЕ объявления = "+b+"</p>"); document.write("<p>Значение <strong>let c </strong> ДО объявления = "+c+"</p>"); //Ошибка в консоли Uncaught ReferenceError: c is not defined let c = 19; document.write("<p>Значение <strong>let c </strong> ПОСЛЕ объявления = "+c+"</p>"); </script> |
Кстати, переменные с let
нельзя объявлять дважды. Такой код приведет к ошибке типа :
1 2 3 4 |
let m = 125; document.write("<p>Первое объявление <strong>let m</strong> = "+m+"</p>"); let m = 480; document.write("<p>Второе объявление <strong>let m</strong> = "+m+"</p>"); |
Также нельзя объявить сначала переменную с помощью var
, а затем пытаться объявить такую же с помощью let
.
Примечание: если вы только начинаете работать с JavaScript, для тестирования кода вам понадобится консоль, которая открывается в любом браузере при нажатии на кнопку F12
, а затем ESC или выбираете вкладку Console.
Использование let в цикле
Поскольку в цикле есть фигурные скобки, использование ключевого слова let
для счетчика ограничит область видимости счетчика фигурными скобками цикла. Ранее при использовании ключевого слова var
переменная, объявленная в скобках, после отработки цикла имела значение, после которого цикл прерывался. На данный момент при объявлении с помощью let
, эта переменная перестает существовать, поэтому попытка ее вывести вызывает ошибку.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
document.write("<p>i="+i+"</p><ol>"); console.log(j); //выводит в консоль //Uncaught ReferenceError: j is not defined for(var i=1; i<6;i++){ document.write("<li>В цикле <strong>var</strong> i="+i+"<//li>"); } document.write("</ol><p>После цикла <strong>var</strong> i="+i+"</p><ol>"); for(let j=1; j<6;j++){ document.write("<li>В цикле <strong>let</strong> j="+j+"</li>"); } document.write('</ol>'); document.write("<p>После цикла <strong>let</strong> j="+j+"</p>"); //выводит в консоль //Uncaught ReferenceError: j is not defined |
В примере ниже видно, что значение переменной i = 6
после цикла, а j
не существует вне скобок.
Константы в JavaScript
Если необходимо определить некую переменную, которая на протяжении выполнения сценария не должна менять свое значение, удобно сделать это с помощью ключевого слова const
.
Например, необходимо использовать некий цвет, который не будет меняться:
1 2 3 4 5 6 |
const lightGreen = "#c3ff19"; dooGreen.onclick=function(){ mytest.style.backgroundColor = lightGreen; lightGreen = "#fff"; //будет выведена ошибка //Uncaught TypeError: Assignment to constant variable } |
Если необходимо константе присвоить какой-либо объект, то поведение несколько поменяется - вы не сможете изменить саму константу, а свойства внутри нее - вполне:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
const animal ={ type: "Cat", name: "Marissa" }; console.log(animal); //изменяем свойства объекта, присвоенного в константу animal.type = "Dog"; animal.name = "Rex"; console.log(animal); //пытаемся переопределить константу animal ={ type: "Dog", name: "Rex" } console.log(animal); //ошибка Uncaught TypeError: Assignment to constant variable. |
Такой же примерно механизм работает, если константе присвоен массив. Вы можете изменять значения элементов массива, обращаясь к ним по индексу, но не можете заменить массив на аналогичный.
1 2 3 4 5 6 7 |
const arr = [0, 1, 5, 12]; console.log(arr); arr[0] = 82; arr[1] = 35; console.log(arr); arr = [82, 35, 5, 12]; console.log(arr); // ошибка Assignment to constant variable. |