const
Значение констант не может быть изменено новым присваиванием, а также не может быть переопределено. Константы ( const ) подчиняются области видимости уровня блока так же, как переменные, объявленные с использованием ключевого слова let .
Синтаксис
const name1 = value1 [, name2 = value2 [, . [, nameN = valueN]]];
Имя константы. Подчиняется тем же правилам, что и идентификаторы обычных переменных.
Значение константы. Может быть любым из тех типов, которые могут быть для переменных, включая функцию.
Описание
Это объявление создаёт константу, чья область действия может быть как глобальной, так и локальной внутри блока, в котором она объявлена. Глобальные константы не становятся свойствами объекта window, в отличие от var -переменных. Инициализация константы обязательна; необходимо указать значение одновременно с объявлением (смысл в том, что потом это значение изменить уже нельзя).
const создаёт константу (новую именованную ссылку на область памяти), доступную только для чтения. Это не означает, что указываемое значение неизменно, но это означает, что идентификатор не может быть переназначен. Например, если константа указывает на объект, то сам объект может быть изменён.
Все соображения по поводу временных мёртвых зон, применимы и к let и к const .
Имена констант не могут совпадать с именами функций или переменных той же области видимости.
Примеры
Ниже описаны примеры, демонстрирующие поведение const . Попробуйте их выполнить в простом JavaScript-редакторе или в консоли браузера.
// Примечание: Идентификаторы констант могут быть объявлены как в верхнем, // так и в нижнем регистре. Но правилом хорошего тона является использование // верхнего регистра. // определим MY_FAV как константу и присвоим ей значение 7 const MY_FAV = 7; // данное присваивание выдаст ошибку - Uncaught TypeError: Assignment to constant variable. MY_FAV = 20; // напечатает 7 console.log("my favorite number is: " + MY_FAV); // попробуем переопределить константу, будет брошено исключение - Uncaught SyntaxError: Identifier 'MY_FAV' has already been declared const MY_FAV = 20; // имя MY_FAV зарезервировано константой выше, данная операция // выкинет исключение var MY_FAV = 20; // здесь также будет ошибка let MY_FAV = 20; // Важно отметить свойства области видимости уровня блока if (MY_FAV === 7) // Всё нормально. Создать константу или переменную MY_FAV можно. // (работает так же как и let при объявлении в блоке переменных, которые не const) const MY_FAV = 20; // MY_FAV теперь 20 console.log("my favorite number is " + MY_FAV); // это попадёт в глобальный контекст и выдаст ошибку var MY_FAV = 20; > // MY_FAV все ещё имеет значение 7 console.log("my favorite number is " + MY_FAV); // Выдаст ошибку, потому что константа не инициализирована - Uncaught SyntaxError: Missing initializer in const declaration const FOO; // const также работает с объектами const MY_OBJECT = "key": "value">; // Попытка переопределить ссылку на объект вызовет исключение - Uncaught TypeError: Assignment to constant variable. MY_OBJECT = "OTHER_KEY": "value">; // но, свойства объекта (ключи) можно изменять MY_OBJECT.key = "otherValue"; // Используйте Object.freeze() для того, чтобы сделать объект неизменяемым // То же самое применимо к массивам const MY_ARRAY = []; // Например, можно добавлять элементы в массив MY_ARRAY.push("A"); // ["A"] // Но менять ссылку на объект массива нельзя. Это вызовет исключение - Uncaught TypeError: Assignment to constant variable MY_ARRAY = ["B"]
Спецификация
Specification |
---|
ECMAScript Language Specification # sec-let-and-const-declarations |
Поддержка браузерами
BCD tables only load in the browser
Смотрите также
- var
- let
- Константы в справочнике JavaScript
Переменные: let и const
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
В ES-2015 предусмотрены новые способы объявления переменных: через let и const вместо var .
let a = 5;
let
У объявлений переменной через let есть три основных отличия от var :
-
Область видимости переменной let – блок <. >. Как мы помним, переменная, объявленная через var , видна везде в функции. Переменная, объявленная через let , видна только в рамках блока <. >, в котором объявлена. Это, в частности, влияет на объявления внутри if , while или for . Например, переменная через var :
var apples = 5; if (true) < var apples = 10; alert(apples); // 10 (внутри блока) >alert(apples); // 10 (снаружи блока то же самое)
В примере выше apples – одна переменная на весь код, которая модифицируется в if . То же самое с let будет работать по-другому:
let apples = 5; // (*) if (true) < let apples = 10; alert(apples); // 10 (внутри блока) >alert(apples); // 5 (снаружи блока значение не изменилось)
Здесь, фактически, две независимые переменные apples , одна – глобальная, вторая – в блоке if . Заметим, что если объявление let apples в первой строке (*) удалить, то в последнем alert будет ошибка: переменная не определена:
if (true) < let apples = 10; alert(apples); // 10 (внутри блока) >alert(apples); // ошибка!
alert(a); // undefined var a = 5;
С переменными let всё проще. До объявления их вообще нет. Такой доступ приведёт к ошибке:
alert(a); // ошибка, нет такой переменной let a = 5;
Заметим также, что переменные let нельзя повторно объявлять. То есть, такой код выведет ошибку:
let x; let x; // ошибка: переменная x уже объявлена
Это – хоть и выглядит ограничением по сравнению с var , но на самом деле проблем не создаёт. Например, два таких цикла совсем не конфликтуют:
// каждый цикл имеет свою переменную i for(let i = 0; i for(let i = 0; i alert( i ); // ошибка: глобальной i нет
for(var i=0; i alert(i); // 10
С переменной let – всё по-другому. Каждому повторению цикла соответствует своя независимая переменная let . Если внутри цикла есть вложенные объявления функций, то в замыкании каждой будет та переменная, которая была при соответствующей итерации. Это позволяет легко решить классическую проблему с замыканиями, описанную в задаче Армия функций.
function makeArmy() < let shooters = []; for (let i = 0; i < 10; i++) < shooters.push(function() < alert( i ); // выводит свой номер >); > return shooters; > var army = makeArmy(); army[0](); // 0 army[5](); // 5
const
Объявление const задаёт константу, то есть переменную, которую нельзя менять:
const apple = 5; apple = 10; // ошибка
В остальном объявление const полностью аналогично let .
Заметим, что если в константу присвоен объект, то от изменения защищена сама константа, но не свойства внутри неё:
const user = < name: "Вася" >; user.name = "Петя"; // допустимо user = 5; // нельзя, будет ошибка
То же самое верно, если константе присвоен массив или другое объектное значение.
константы и КОНСТАНТЫ
Константы, которые жёстко заданы всегда, во время всей программы, обычно пишутся в верхнем регистре. Например: const ORANGE = «#ffa500» .
Большинство переменных – константы в другом смысле: они не меняются после присвоения. Но при разных запусках функции это значение может быть разным. Для таких переменных можно использовать const и обычные строчные буквы в имени.
Итого
- Видны только после объявления и только в текущем блоке.
- Нельзя переобъявлять (в том же блоке).
- При объявлении переменной в цикле for(let …) – она видна только в этом цикле. Причём каждой итерации соответствует своя переменная let .
Переменная const – это константа, в остальном – как let .
JavaScript: Константы
Во всем модуле подавляющее большинство примеров кода использовало переменные в качестве имен (псевдонимы) конкретных значений, а не как переменные, которые меняют свое значение со временем.
let dollarsInEuro = 1.25; let rublesInDollar = 60; let dollarsCount = 50 * dollarsInEuro; // 62.5 let rublesCount = dollarsCount * rublesInDollar; // 3750 console.log(rublesCount);
В программировании принято называть такие имена константами, и многие языки поддерживают константы как конструкцию. JavaScript, как раз, относится к таким языкам, и его стандарты кодирования говорят прямо — если значение не меняется, то мы имеем дело с константой. Перепишем пример выше на использование констант:
const dollarsInEuro = 1.25; const rublesInDollar = 60; const euros = 1000; const dollars = euros * dollarsInEuro; // 1250 const rubles = dollars * rublesInDollar; // 75000 console.log(rubles);
Единственное изменение заключается в том, что ключевое слово let заменилось на const , но это только синтаксис. Теперь, если попытаться изменить любую константу, то мы получим сообщение об ошибке. В остальном они используются точно так же, как и переменные.
const pi = 3.14; pi = 5; // TypeError: Assignment to constant variable.
Зачем такие сложности? Почему бы не оставить только переменные? Даже если бы мы оставили только переменные, то это не отменяет того факта, что они часто использовались бы как константы, более того, код на JavaScript можно и идиоматично писать без использования переменных вообще. Посмотрите на пример из реального кода Хекслета. На текущем этапе вы его вряд ли поймете, но попробуйте посчитать количество констант и переменных внутри него, вы увидите, что здесь ровно одна переменная, и целая куча констант.
Константы значительно проще для анализа, когда мы видим константу в коде, то нам сразу понятно, что ее значение всегда остается прежним. При использовании констант отсутствует понятие времени. С переменными все не так, мы не можем быть уверены в их значении, приходится анализировать весь код, чтобы понять, как они могли измениться.
Переменные жизненно необходимы только в одном случае (во всех остальных гарантировано можно обойтись без них) — при работе с циклами, до которых мы ещё дойдем.
В дальнейшем мы будем предпочитать константы и использовать переменные только тогда, когда без них никак.
Задание
Создайте константу army , присвойте ей значение the white walkers и распечатайте её значение на экран.
Упражнение не проходит проверку — что делать?
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя
Это нормально , в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.
Чем различаются var, let и const в JavaScript
На практике разбираемся, чем различаются var, let и const и когда их использовать.
Иллюстрация: Катя Павловская для Skillbox Media
Евгений Кучерявый
Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.
Переменные в JavaScript можно создавать тремя способами — c помощью ключевых слов var, let и const. Они выполняют одну и ту же функцию (объявляют о создании именованной ячейки в памяти), но работают немного по-разному.
Содержание:
- Что такое объявление, инициализация и область видимости
- Как работает var и что с ней не так
- Как работает let и чем она отличается от var
- Объявление констант с помощью оператора const
Объявление, инициализация и область видимости переменной в JavaScript
Перед тем как обсуждать отличия var, let и const, разберёмся с некоторыми базовыми понятиями.
Программы на JavaScript хранят числа, строки, логические значения и более сложные объекты в именованных ячейках памяти — переменных. Данные из этих ячеек можно применять в расчётах, выводить на экран и перезаписывать. К переменным обращаются по уникальному имени, или идентификатору.
Объявить переменную — значит ввести новый идентификатор в программу.
До выхода стандарта ECMAScript 6 переменные в JavaScript объявляли только с помощью ключевого слова var:
var best_podcast
Когда интерпретатор JavaScript находит очередное объявление с var, он выделяет место в памяти и по умолчанию присваивает элементу значение undefined — то есть «неопределённое». Также undefined можно получить, если обратиться к несуществующим элементам массива и свойствам объекта.
Обращение к неопределённому значению может привести к непредсказуемым ошибкам, поэтому рекомендуется как можно раньше давать переменным начальное значение — то есть инициализировать их. Делается это с помощью оператора =:
best_podcast = 'people and code';
Мы можем выводить переменную best_podcast на экран и перезаписывать её сколько угодно. Главное — чтобы в момент обращения программа её «видела». Да, в разные моменты времени переменные то скрываются, то появляются в поле зрения интерпретатора JavaScript.
Часть программы, в которой доступен тот или иной идентификатор, называют областью видимости переменной.
В зависимости от области видимости в JavaScript различают локальные (functional scope) и глобальные (global scope) переменные. Локальные создаются внутри функции и доступны только в её пределах. А глобальные объявляются вне функций и видны в любой точке программы. Именно в работе с областью видимости и заключаются различия между var и let.
Как работает var и что с ней не так
Переменная var, созданная вне функции, действует как глобальная переменная — она доступна из любой части скрипта.
var a = 10; function func( ) < //Переменная создана глобально, поэтому её можно использовать где угодно a = 50; > func(); //Будет выведено 50 console.log(a);
Если же создать переменную с помощью var внутри функции, то она будет локальной, то есть доступной только в этой функции:
function func( ) < var a = 10; > func(); //Выведет ошибку, потому что переменная a доступна только внутри функции func() console.log(a);
Это позволяет создавать переменные с одинаковыми названиями и обращаться к внешним переменным через специальный объект window:
var x = 50; function func( ) < var x = 10; //Будет выведено 10 console.log(x); //Будет выведено 50 console.log(window.x); >
Не стоит привыкать к var. Использование этого ключевого слова в 2022 году считается плохой практикой по нескольким причинам.
Отсутствие блочной области видимости. Var-переменная, созданная в блоке if‑else или цикле, доступна за пределами своего блока. Например, в C++ или Java не получится получить доступ к счётчику цикла нигде, кроме тела этого цикла, а вот в JavaScript, если счётчик объявлен как var, — получится легко. Это практически всегда приводит к труднораспознаваемым логическим ошибкам.
Повторное объявление. Переменные var можно создавать повторно, и компилятор не будет ругаться. Почему это плохо? Допустим, в вашем JS-файле 4000 строк кода. Вы объявили на 5-й строке переменную books, которая хранит количество PDF-книг на сайте. А затем, добравшись до 3005-й строки, забыли об этом и создали другую переменную books — только теперь она хранит количество книг в корзине покупателя. Даже если вы уверены, что всегда сможете отличить одну переменную от другой, то программисты, которые будут работать с вашим кодом, точно не скажут вам спасибо.
«Поднятие» переменной, или hoisting. Все переменные var считаются объявленными перед запуском скрипта. При этом они остаются undefined до тех пор, пока не выполнится код инициализации.
function showPodcast( ) < //Вызовем переменную перед её объявлением best_podcast = 'people and code'; if(false) < var best_podcast; > console.log(best_podcast); > showPodcast(); //Ошибки не будет, браузер выведет undefined
Если запустить приведённый выше код, компилятор выведет название лучшего подкаста про IT. Но почему? Ведь мы инициализировали переменную до того, как её определили. По «нормальной» логике интерпретатор должен вернуть сообщение об ошибке, потому что блок if никогда не выполнится и переменная не будет определена. Но с var такие парадоксы — обычное дело.
В современном JS есть более однозначный и логичный способ определения переменных. Тем не менее вы не раз столкнётесь с var в легаси-коде, поэтому знать о нём полезно.
Как работает let и чем она отличается от var
Ключевое слово let лишено недостатков своего предшественника. Переменные, объявленные с его помощью, нельзя объявить повторно — программа выдаст ошибку. Let-переменные тоже «всплывают», но при попытке обратиться к ним до инициализации вы получите ошибку ReferenceError.
function showPodcast < //Вызовем переменную перед её объявлением console.log(best_podcast); let best_podcast = 'people and code'; > showPodcast(); //Получим ошибку. Спасибо, машина!
Но главное — такие переменные имеют блочную область видимости. А значит, они доступны только внутри того блока <>, в котором были созданы:
let a = 5; if(true) < let b = 5; > //Будет выведено, потому что переменная a объявлена вне какого-либо блока и доступна глобально console.log(a); //Вызовет ошибку, потому что переменная b объявлена внутри блока if и доступна только в нём console.log(b);
Вот как различается поведение счётчика цикла, если его создавать с помощью var и с помощью let:
//Переменная i доступна за пределами цикла
//Переменная i доступна только внутри цикла
//Попытка использовать её приведёт к ошибке
В остальном поведение этих переменных идентично.
Объявление констант с помощью оператора const
С помощью ключевого слова const создаются константы. Например, физические и математические величины.
const Pi = 3.14; const c = 299792458; const g = 9.8;
Попытка изменить значение константы приведёт к ошибке. Поэтому их стоит использовать для хранения данных, которые должны оставаться неизменными.
Например, в них можно хранить объекты из DOM:
const content = document.getElementById("content");
Также стоит отметить, что неизменяемым сохраняется сам объект, а не его поля:
const obj = < x: 1, y: 5, z: 12 >; //Возможно obj.x = 5; //Выдаст ошибку obj = 1; //Попытка задать другой объект тоже приведёт к ошибке obj = < x: 51, y: 12, z: 8 >;
Что касается областей видимости, то const ведёт себя как let — разницы между ними нет.
Обратите внимание: let и const являются частью стандарта ECMAScript 6, который поддерживается не всеми браузерами. Заранее ознакомьтесь с таблицей совместимости.
Заключение
В большинстве случаев достаточно использовать var, но иногда необходимо убедиться, что ваши данные в сохранности — их нельзя изменить извне или изменить в принципе. В этих случаях let и const незаменимы.