Variables
Last updated
Last updated
Большинству программ нужно отслеживать то, как меняется значение на протяжении выполнения программы проходя через различные операции, вызываемые для соответствующих задач вашей программы.
Самый простой путь сделать это в программе — присвоить значение символьному контейнеру, называемому переменной (variable), т.к. при необходимости значение в этом контейнере может меняться с течением времени.
В некоторых языках программирования вы определяете переменную (контейнер), чтобы хранить определенный тип значения, такой какчисло
илистрока
. Статическая типизация, также известная как контроль типов, обычно упоминается как преимущество в корректности программы, предотвращая непредусмотренные преобразования значений.
Другие языки выводят типы для значений вместо переменных. Слабая типизация, также известная как динамическая типизация, позволяет переменной хранить значения любого типа в любое время. Это обычно упоминается как преимущество в гибкости программы, позволяя одной переменной представлять значение вне зависимости от того, в форме какого типа это значение может понадобиться в любой момент выполнения программы.
JavaScript использует второй подход: динамическую типизацию, что означает, что переменные могут хранить значения любого типа без какого-либо контроля типов.
Вы можете использовать переменные как символические имена для значений в вашем приложении. Имена переменных называются identifiers и должны соответствовать определенным правилам.
Идентификатор в JavaScript должен начинаться с буквы, нижнего подчеркивания (_) или знака доллара ($); последующие символы могут также быть цифрами (0-9). Поскольку JavaScript чувствителен к регистру, буквы включают символы от "A" до "Z" (верхний регистр) и символы от "a" до "z" (нижний регистр).
Вы можете использовать в идентификаторах буквы ISO 8859-1 или Unicode, например, å или ü. Вы также можете использовать управляющие последовательности Unicode как символы в идентификаторах.
В общем-то, те же правила, применяемые к идентификатору переменной, применяются и к имени свойства. Однако определенные слова не используются как переменные, но могут использоваться как имена свойств. Эти слова называются "зарезервированными словами" и включают ключевые слова JS (for
,in
,if
и т.д.), включая иnull
,true
иfalse
.
Некоторые примеры корректных имен: Number_hits
, temp99
, _name
.
Вы можете назвать переменную как угодно, но есть ограничения. Как правило, вы должны придерживаться только латинских символов (0-9, a-z, A-Z) и символа подчеркивания.
Не используйте символы подчеркивания в начале имен переменных, т.к они используются в некоторых конструкциях JavaScript для обозначения конкретных вещей, поэтому можно запутаться.
Не используйте числа в начале переменных. Это недопустимо и приведет к ошибке.
Общепринято придерживаться так называемого "lower camel case", где вы склеиваете несколько слов, используя строчные буквы для целого первого слова, а затем заглавные буквы следующих слов. Мы использовали для наших имен переменные в данной статье.
Делайте имена переменных такими, чтобы было интуитивно понятно, какие данные они содержат. Не используйте только отдельные буквы / цифры или большие длинные фразы.
В JavaScript существует три вида объявлений переменных:
var
- Объявляет переменную, инициализация переменной значением является необязательной.
let
- Объявляет локальную переменную в области видимости блока, инициализация переменной значением является необязательной.
const
- Объявляет именованную константу, доступную только для чтения.
Переменные можно объявить следующими способами:
Используя ключевое слово var
. Например, var x = 42
. Данный синтаксис может быть использован для объявления как локальных, так и глобальных переменных.
Просто присвоить переменной значение. Например, x = 42
. Переменные, объявленные данным способом, являются глобальными. Такое объявление генерирует строгое предупреждение (strict mode). Не рекомендуется использовать данный способ.
Используя ключевое слово let
. Например, let y = 13
. Данный синтаксис может быть использован для объявления локальной переменной в области видимости блока.
В обычном режиме выполнения JavaScript опечатка в имени переменной во время присваивания приводит к созданию нового свойства глобального объекта, и выполнение продолжается (хотя в современном JavaScript оно, вероятно, аварийно завершится далее). Присваивания, которые могут случайно создать глобальную переменную, в строгом режиме (strict mode) выбрасывают исключение:
Переменная, объявленная через var
или let
без присвоения начального значения, имеет значение undefined
. При попытке доступа к необъявленной переменной или переменной до её объявления будет выброшено исключение ReferenceError
:
Когда переменной присваивается значение, вы можете изменить (обновить) это значение, просто указав другое значение. Попробуйте ввести следующие строки в консоль:
Cтрогий режим заставляет присваивания, которые все равно завершились бы неудачей, выбрасывать исключения. Например, NaN -- глобальная переменная, защищенная от записи. В обычном режиме присваивание NaN-значения ничего не делает; разработчик не получает никакого сообщения об ошибке. В строгом режиме присваивание значения NaN выбрасывает исключение. Любое присваивание, которое в обычном режиме завершается неудачей (присваивание значения свойству, защищенному от записи; присваивание значения свойству, доступному только для чтения; присваивание нового свойства нерасширяемому объекту) в строгом режиме выбросит исключение:
Когда вы объявляете переменную вне функции, то такая переменная называется глобальной переменной, т.к. доступна любому коду в текущем документе. Когда вы объявляете переменную внутри функции, то такая переменная называется локальной переменной, т.к. доступна только внутри данной функции.
До ECMAScript 6 в JavaScript отсутствовала область видимости блока; переменная, объявленная внутри блока, является локальной для функции (или глобальной области видимости), внутри которой находится данный блок. Например, следующий код выведет значение 5, т.к. областью видимости переменной x
является функция (или глобальный контекст), внутри которой объявлена переменная x
, а не блок, которым в данном случае является оператор if
:
Такое поведение меняется, если используется операторlet
, введенный в ECMAScript 6:
Вы используете ключевое словоvar
, чтобы объявить переменную, которая принадлежит области видимости текущей функции или глобальной области, если находится на верхнем уровне вне любой функции.
Где бы ни появлялось var
внутри области видимости, это объявление принадлежит всей области видимости и доступно в ней повсюду.
Это поведение называется поднятие (hoisting), когда объявление var
концептуально "перемещается" на вершину своей объемлющей области видимости. Технически этот процесс более точно объясняется тем, как компилируется код, но сейчас опустим эти подробности.
Пример:
Не общепринято и не так уж здраво полагаться на поднятие переменной, чтобы использовать переменную в ее области видимости раньше, чем появится ее объявление var
: такое может сбить с толку. Общепринято и приемлемо использовать всплытие объявлений функций, что мы и делали с вызовом foo()
, появившимся до ее объявления.
Когда вы объявляете переменную, она доступна повсюду в области ее видимости так же, как и в более нижних/внутренних областях видимости. Например:
Заметьте, чтоc
недоступна внутри bar()
, потому что она объявлена только внутри внутренней области видимостиbaz()
иb
недоступна вfoo()
по той же причине.
Если вы попытаетесь получить доступ к значению переменной в области видимости, где она уже недоступна, вы получите ReferenceError
. Если вы попытаетесь установить значение переменной, которая еще не объявлена, у вас закончится все тем, что переменная создастся в самой верхней глобальной области видимости (плохо!), либо получите ошибку в зависимости от "строгого режима" (см. "Строгий режим"). Давайте посмотрим:
Это очень плохая практика. Не делайте так! Всегда явно объявляйте свои переменные.
В дополнение к созданию объявлений переменных на уровне функций, ES6 позволяет вам объявлять переменные, принадлежащие отдельным блокам (пара{ .. }
), используя ключевое слово let
. Кроме некоторых едва уловимых деталей, правила области видимости будут вести себя точно так же, как мы видели в функциях:
Из-за использования let
вместо var
,b
будет принадлежать только оператору if
и, следовательно, не всей области видимости функции foo()
. Точно так же c
принадлежит только циклу while
. Блочная область видимости очень полезна для управления областями ваших переменных более точно, что может сделать ваш код более легким в обслуживании в долгосрочной перспективе.