Что такое var в javascript
Оператор var объявляет переменную, инициализируя её, при необходимости.
Интерактивный пример
Синтаксис
var varname1 [= value1 [, varname2 [, varname3 . [, varnameN]]]];
Имя переменной. Может использоваться любой допустимый идентификатор.
Значение переменной. Любое допустимое выражение. По умолчанию значение undefined.
Описание
Объявление переменной всегда обрабатывается до выполнения кода, где бы она ни находилась. Область видимости переменной, объявленной через var , это её текущий контекст выполнения. Который может ограничиваться функцией или быть глобальным, для переменных, объявленных за пределами функции.
Присвоение значения необъявленной переменной подразумевает, что она будет создана как глобальная переменная (переменная становится свойством глобального объекта) после выполнения присваивания значения. Различия между объявленной и необъявленной переменными следующие:
1. Объявленные переменные ограничены контекстом выполнения, в котором они были объявлены. Необъявленные переменные всегда глобальны.
function x() y = 1; // возбудит ReferenceError в "строгом режиме" var z = 2; > x(); console.log(y); // выведет "1" console.log(z); // возбудит ReferenceError: z не определён вне x
2. Объявленные переменные инициализируются до выполнения любого кода. Необъявленные переменные не существуют до тех пор, пока к ним не выполнено присваивание.
.log(a); // Возбудит ReferenceError. console.log("still going. "); // Не выполнится.
var a; console.log(a); // Выведет "undefined" или "", в зависимости от браузера. console.log("still going. "); // Выведет "still going. ".
3. Объявленные переменные, независимо от контекста выполнения, являются ненастраиваемыми свойствами. Необъявленные переменные это настраиваемые свойства (т.е. их можно удалять).
var a = 1; b = 2; delete this.a; // Возбудит TypeError в "строгом режиме". В "нестрогом режиме" будет ошибка без уведомления. delete this.b; console.log(a, b); // Возбудит ReferenceError. // Свойство 'b' было удалено и больше не существует.
Из-за перечисленных различий, использование необъявленных переменных может привести к непредсказуемым последствиям. Рекомендовано всегда объявлять переменные, вне зависимости, находятся они внутри функции или в глобальном контексте. Присваивание значения необъявленной переменной в строгом режиме (en-US) ECMAScript 5 возбуждает ошибку.
Поднятие переменных
Объявление переменных (как и любые другие объявления) обрабатываются до выполнения кода. Где бы не находилось объявление, это равнозначно тому, что переменную объявили в самом начале кода. Это значит, что переменная становится доступной до того, как она объявлена. Такое поведение называется «поднятием» (в некоторых источниках «всплытием»).
= 2; var bla; // . // читается как: var bla; bla = 2;
Поэтому объявление переменных рекомендовано выносить в начало их области видимости (в начало глобального кода или в начало функции). Это даёт понять какие переменные принадлежат функции (т.е. являются локальными), а какие обрабатываются в цепи областей видимости (т.е. являются глобальными).
Важно отметить, что подъем будет влиять на объявление переменной, но не на инициализацию её значения. Значение присваивается при выполнении оператора присваивания:
function do_something() console.log(bar); // выведет undefined var bar = 111; console.log(bar); // выведет 111 > // . неявно понимается как: function do_something() var bar; console.log(bar); // выведет undefined bar = 111; console.log(bar); // выведет 111 >
Что такое var в JavaScript?
Типы переменных в языке JavaScript не объявляются очевидно, тем не менее они присутствуют. Интерпретатор понимает что записывается в переменную и на основании этого добавляет тип к этой переменной.
В ходе программы мы можем перезаписывать значение переменной, при этом мы можем указывать новый тип переменной.
К примеру, изначально был записан тип float (число с точкой), но потом можно записать другой тип данных:
var first_num = 23.2 // Тип данных float var first_num = "1" // Тип данных string
Ниже приводим несколько существующих типов данных в языке JavaScript:
- var some = 1 Integer — целые числа;
- var some = 1.12 Float — числа с плавающей точкой;
- var some = «Привет» String — строки;
- var some = true Boolean — принимают только true или же false.
Устаревшее ключевое слово «var»
Информация, приведенная в этой статье, полезна для понимания старых скриптов.
Мы не пишем современный код таким образом.
В самой первой главе про переменные мы ознакомились с тремя способами объявления переменных:
let и const ведут себя одинаково по отношению к лексическому окружению, области видимости.
Но var – это совершенно другой зверь, берущий своё начало с давних времён. Обычно var не используется в современных скриптах, но всё ещё может скрываться в старых.
Если в данный момент вы не работаете с подобными скриптами, вы можете пропустить или отложить прочтение данной главы, однако, есть шанс, что вы столкнётесь с var в будущем.
На первый взгляд, поведение var похоже на let . Например, объявление переменной:
function sayHi() < var phrase = "Привет"; // локальная переменная, "var" вместо "let" alert(phrase); // Привет >sayHi(); alert(phrase); // Ошибка: phrase не определена
…Однако, отличия всё же есть.
Для «var» не существует блочной области видимости
Область видимости переменных var ограничивается либо функцией, либо, если переменная глобальная, то скриптом. Такие переменные доступны за пределами блока.
if (true) < var test = true; // используем var вместо let >alert(test); // true, переменная существует вне блока if
Так как var игнорирует блоки, мы получили глобальную переменную test .
А если бы мы использовали let test вместо var test , тогда переменная была бы видна только внутри if :
if (true) < let test = true; // используем let >alert(test); // Error: test is not defined
Аналогично для циклов: var не может быть блочной или локальной внутри цикла:
for (var i = 0; i < 10; i++) < // . >alert(i); // 10, переменная i доступна вне цикла, т.к. является глобальной переменной
Если блок кода находится внутри функции, то var становится локальной переменной в этой функции:
function sayHi() < if (true) < var phrase = "Привет"; >alert(phrase); // срабатывает и выводит "Привет" > sayHi(); alert(phrase); // Ошибка: phrase не определена (видна в консоли разработчика)
Как мы видим, var выходит за пределы блоков if , for и подобных. Это происходит потому, что на заре развития JavaScript блоки кода не имели лексического окружения. Поэтому можно сказать, что var – это пережиток прошлого.
«var» допускает повторное объявление
Если в блоке кода дважды объявить одну и ту же переменную let , будет ошибка:
let user; let user; // SyntaxError: 'user' has already been declared
Используя var , можно переобъявлять переменную сколько угодно раз. Повторные var игнорируются:
var user = "Пётр"; var user; // ничего не делает, переменная объявлена раньше // . нет ошибки alert(user); // Пётр
Если дополнительно присвоить значение, то переменная примет новое значение:
var user = "Пётр"; var user = "Иван"; alert(user); // Иван
«var» обрабатываются в начале запуска функции
Объявления переменных var обрабатываются в начале выполнения функции (или запуска скрипта, если переменная является глобальной).
Другими словами, переменные var считаются объявленными с самого начала исполнения функции вне зависимости от того, в каком месте функции реально находятся их объявления (при условии, что они не находятся во вложенной функции).
function sayHi() < phrase = "Привет"; alert(phrase); var phrase; >sayHi();
…Технически полностью эквивалентен следующему (объявление переменной var phrase перемещено в начало функции):
function sayHi() < var phrase; phrase = "Привет"; alert(phrase); >sayHi();
…И даже коду ниже (как вы помните, блочная область видимости игнорируется):
function sayHi() < phrase = "Привет"; // (*) if (false) < var phrase; >alert(phrase); > sayHi();
Это поведение называется «hoisting» (всплытие, поднятие), потому что все объявления переменных var «всплывают» в самый верх функции.
В примере выше if (false) условие никогда не выполнится. Но это никаким образом не препятствует созданию переменной var phrase , которая находится внутри него, поскольку объявления var «всплывают» в начало функции. Т.е. в момент присвоения значения (*) переменная уже существует.
Объявления переменных «всплывают», но присваивания значений – нет.
Это проще всего продемонстрировать на примере:
function sayHi() < alert(phrase); var phrase = "Привет"; >sayHi();
Строка var phrase = «Привет» состоит из двух действий:
- Объявление переменной var
- Присвоение значения в переменную = .
Объявление переменной обрабатывается в начале выполнения функции («всплывает»), однако присвоение значения всегда происходит в той строке кода, где оно указано. Т.е. код выполняется по следующему сценарию:
function sayHi() < var phrase; // объявление переменной срабатывает вначале. alert(phrase); // undefined phrase = "Привет"; // . присвоение - в момент, когда исполнится данная строка кода. >sayHi();
Поскольку все объявления переменных var обрабатываются в начале функции, мы можем ссылаться на них в любом месте. Однако, переменные имеют значение undefined до строки с присвоением значения.
В обоих примерах выше вызов alert происходил без ошибки, потому что переменная phrase уже существовала. Но её значение ещё не было присвоено, поэтому мы получали undefined .
IIFE
В прошлом, поскольку существовал только var , а он не имел блочной области видимости, программисты придумали способ её эмулировать. Этот способ получил название «Immediately-invoked function expressions» (сокращенно IIFE).
Это не то, что мы должны использовать сегодня, но, так как вы можете встретить это в старых скриптах, полезно понимать принцип работы.
IIFE выглядит следующим образом:
(function() < var message = "Привет"; alert(message); // Привет >)();
Здесь создаётся и немедленно вызывается Function Expression. Так что код выполняется сразу же и у него есть свои локальные переменные.
Function Expression обёрнуто в скобки (function <. >) , потому что, когда JavaScript встречает «function» в основном потоке кода, он воспринимает это как начало Function Declaration. Но у Function Declaration должно быть имя, так что такой код вызовет ошибку:
// Пробуем объявить и сразу же вызвать функцию function() < // ();
Даже если мы скажем: «хорошо, давайте добавим имя», – это не сработает, потому что JavaScript не позволяет вызывать Function Declaration немедленно.
// ошибка синтаксиса из-за скобок ниже function go() < >(); //
Так что скобки вокруг функции – это трюк, который позволяет объяснить JavaScript, что функция была создана в контексте другого выражения, а значит, что это Function Expression: ей не нужно имя и её можно вызвать немедленно.
Помимо круглых скобок существуют и другие способы сообщить JavaScript, что мы имеем в виду Function Expression:
// Способы создания IIFE (function() < alert("Круглые скобки вокруг функции"); >)(); (function() < alert("Круглые скобки вокруг всего выражения"); >()); !function() < alert("Выражение начинается с логического оператора НЕ"); >(); +function() < alert("Выражение начинается с унарного плюса"); >();
Во всех перечисленных случаях мы объявляем Function Expression и немедленно запускаем его. Ещё раз отметим: в настоящее время необходимости писать подобный код нет.
Итого
Существует 2 основных отличия var от let/const :
- Переменные var не имеют блочной области видимости, они ограничены, как минимум, телом функции.
- Объявления (инициализация) переменных var производится в начале исполнения функции (или скрипта для глобальных переменных).
Есть ещё одно небольшое отличие, относящееся к глобальному объекту, мы рассмотрим его в следующей главе.
Эти особенности, как правило, не очень хорошо влияют на код. Блочная область видимости – это удобно. Поэтому много лет назад let и const были введены в стандарт и сейчас являются основным способом объявления переменных.
Переменные
JavaScript-приложению обычно нужно работать с информацией. Например:
- Интернет-магазин – информация может включать продаваемые товары и корзину покупок.
- Чат – информация может включать пользователей, сообщения и многое другое.
Переменные используются для хранения этой информации.
Переменная
Переменная – это «именованное хранилище» для данных. Мы можем использовать переменные для хранения товаров, посетителей и других данных.
Для создания переменной в JavaScript используйте ключевое слово let .
Приведённая ниже инструкция создаёт (другими словами, объявляет) переменную с именем «message»:
let message;
Теперь можно поместить в неё данные (другими словами, определить переменную), используя оператор присваивания = :
let message; message = 'Hello'; // сохранить строку 'Hello' в переменной с именем message
Строка сохраняется в области памяти, связанной с переменной. Мы можем получить к ней доступ, используя имя переменной:
let message; message = 'Hello!'; alert(message); // показывает содержимое переменной
Для краткости можно совместить объявление переменной и запись данных в одну строку:
let message = 'Hello!'; // определяем переменную и присваиваем ей значение alert(message); // Hello!
Мы также можем объявить несколько переменных в одной строке:
let user = 'John', age = 25, message = 'Hello';
Такой способ может показаться короче, но мы не рекомендуем его. Для лучшей читаемости объявляйте каждую переменную на новой строке.
Многострочный вариант немного длиннее, но легче для чтения:
let user = 'John'; let age = 25; let message = 'Hello';
Некоторые люди также определяют несколько переменных в таком вот многострочном стиле:
let user = 'John', age = 25, message = 'Hello';
…Или даже с запятой в начале строки:
let user = 'John' , age = 25 , message = 'Hello';
В принципе, все эти варианты работают одинаково. Так что это вопрос личного вкуса и эстетики.
var вместо let
В старых скриптах вы также можете найти другое ключевое слово: var вместо let :
var message = 'Hello';
Ключевое слово var – почти то же самое, что и let . Оно объявляет переменную, но немного по-другому, «устаревшим» способом.
Есть тонкие различия между let и var , но они пока не имеют для нас значения. Мы подробно рассмотрим их в главе Устаревшее ключевое слово "var".
Аналогия из жизни
Мы легко поймём концепцию «переменной», если представим её в виде «коробки» для данных с уникальным названием на ней.
Например, переменную message можно представить как коробку с названием "message" и значением "Hello!" внутри:
Мы можем положить любое значение в коробку.
Мы также можем изменить его столько раз, сколько захотим:
let message; message = 'Hello!'; message = 'World!'; // значение изменено alert(message);
При изменении значения старые данные удаляются из переменной:
Мы также можем объявить две переменные и скопировать данные из одной в другую.
let hello = 'Hello world!'; let message; // копируем значение 'Hello world' из переменной hello в переменную message message = hello; // теперь две переменные содержат одинаковые данные alert(hello); // Hello world! alert(message); // Hello world!
Повторное объявление вызывает ошибку
Переменная может быть объявлена только один раз.
Повторное объявление той же переменной является ошибкой:
let message = "Это"; // повторение ключевого слова 'let' приводит к ошибке let message = "Другое"; // SyntaxError: 'message' has already been declared
Поэтому следует объявлять переменную только один раз и затем использовать её уже без let .
Функциональные языки программирования
Примечательно, что существуют функциональные языки программирования, такие как Scala или Erlang, которые запрещают изменять значение переменной.
В таких языках однажды сохранённое «в коробку» значение остаётся там навсегда. Если нам нужно сохранить что-то другое, язык заставляет нас создать новую коробку (объявить новую переменную). Мы не можем использовать старую переменную.
Хотя на первый взгляд это может показаться немного странным, эти языки вполне подходят для серьёзной разработки. Более того, есть такая область, как параллельные вычисления, где это ограничение даёт определённые преимущества. Изучение такого языка (даже если вы не планируете использовать его в ближайшее время) рекомендуется для расширения кругозора.
Имена переменных
В JavaScript есть два ограничения, касающиеся имён переменных:
- Имя переменной должно содержать только буквы, цифры или символы $ и _ .
- Первый символ не должен быть цифрой.
Примеры допустимых имён:
let userName; let test123;
Если имя содержит несколько слов, обычно используется верблюжья нотация, то есть, слова следуют одно за другим, где каждое следующее слово начинается с заглавной буквы: myVeryLongName .
Самое интересное – знак доллара '$' и подчёркивание '_' также можно использовать в названиях. Это обычные символы, как и буквы, без какого-либо особого значения.
Эти имена являются допустимыми:
let $ = 1; // объявили переменную с именем "$" let _ = 2; // а теперь переменную с именем "_" alert($ + _); // 3
Примеры неправильных имён переменных:
let 1a; // не может начинаться с цифры let my-name; // дефис '-' не разрешён в имени
Регистр имеет значение
Переменные с именами apple и APPLE – это две разные переменные.
Нелатинские буквы разрешены, но не рекомендуются
Можно использовать любой язык, включая кириллицу или даже иероглифы, например:
let имя = '. '; let 我 = '. ';
Технически здесь нет ошибки, такие имена разрешены, но есть международная традиция использовать английский язык в именах переменных. Даже если мы пишем небольшой скрипт, у него может быть долгая жизнь впереди. Людям из других стран, возможно, придётся прочесть его не один раз.
Зарезервированные имена
Существует список зарезервированных слов, которые нельзя использовать в качестве имён переменных, потому что они используются самим языком.
Например: let , class , return и function зарезервированы.
Приведённый ниже код даёт синтаксическую ошибку:
let let = 5; // нельзя назвать переменную "let", ошибка! let return = 5; // также нельзя назвать переменную "return", ошибка!
Создание переменной без использования use strict
Обычно нам нужно определить переменную перед её использованием. Но в старые времена было технически возможно создать переменную простым присвоением значения без использования let . Это все ещё работает, если мы не включаем use strict в наших файлах, чтобы обеспечить совместимость со старыми скриптами.
// заметка: "use strict" в этом примере не используется num = 5; // если переменная "num" раньше не существовала, она создаётся alert(num); // 5
Это плохая практика, которая приводит к ошибке в строгом режиме:
"use strict"; num = 5; // ошибка: num is not defined
Константы
Чтобы объявить константную, то есть, неизменяемую переменную, используйте const вместо let :
const myBirthday = '18.04.1982';
Переменные, объявленные с помощью const , называются «константами». Их нельзя изменить. Попытка сделать это приведёт к ошибке:
const myBirthday = '18.04.1982'; myBirthday = '01.01.2001'; // ошибка, константу нельзя перезаписать!
Если программист уверен, что переменная никогда не будет меняться, он может гарантировать это и наглядно донести до каждого, объявив её через const .
Константы в верхнем регистре
Широко распространена практика использования констант в качестве псевдонимов для трудно запоминаемых значений, которые известны до начала исполнения скрипта.
Названия таких констант пишутся с использованием заглавных букв и подчёркивания.
Например, сделаем константы для различных цветов в «шестнадцатеричном формате»:
const COLOR_RED = "#F00"; const COLOR_GREEN = "#0F0"; const COLOR_BLUE = "#00F"; const COLOR_ORANGE = "#FF7F00"; // . когда нам нужно выбрать цвет let color = COLOR_ORANGE; alert(color); // #FF7F00
- COLOR_ORANGE гораздо легче запомнить, чем "#FF7F00" .
- Гораздо легче допустить ошибку при вводе "#FF7F00" , чем при вводе COLOR_ORANGE .
- При чтении кода COLOR_ORANGE намного понятнее, чем #FF7F00 .
Когда мы должны использовать для констант заглавные буквы, а когда называть их нормально? Давайте разберёмся и с этим.
Название «константа» просто означает, что значение переменной никогда не меняется. Но есть константы, которые известны до выполнения (например, шестнадцатеричное значение для красного цвета), а есть константы, которые вычисляются во время выполнения сценария, но не изменяются после их первоначального назначения.
const pageLoadTime = /* время, потраченное на загрузку веб-страницы */;
Значение pageLoadTime неизвестно до загрузки страницы, поэтому её имя записано обычными, а не прописными буквами. Но это всё ещё константа, потому что она не изменяется после назначения.
Другими словами, константы с именами, записанными заглавными буквами, используются только как псевдонимы для «жёстко закодированных» значений.
Придумывайте правильные имена
В разговоре о переменных необходимо упомянуть, что есть ещё одна чрезвычайно важная вещь.
Название переменной должно иметь ясный и понятный смысл, говорить о том, какие данные в ней хранятся.
Именование переменных – это один из самых важных и сложных навыков в программировании. Быстрый взгляд на имена переменных может показать, какой код был написан новичком, а какой – опытным разработчиком.
В реальном проекте большая часть времени тратится на изменение и расширение существующей кодовой базы, а не на написание чего-то совершенно нового с нуля. Когда мы возвращаемся к коду после какого-то промежутка времени, гораздо легче найти информацию, которая хорошо размечена. Или, другими словами, когда переменные имеют хорошие имена.
Пожалуйста, потратьте время на обдумывание правильного имени переменной перед её объявлением. Делайте так, и будете вознаграждены.
Несколько хороших правил:
- Используйте легко читаемые имена, такие как userName или shoppingCart .
- Избегайте использования аббревиатур или коротких имён, таких как a , b , c , за исключением тех случаев, когда вы точно знаете, что так нужно.
- Делайте имена максимально описательными и лаконичными. Примеры плохих имён: data и value . Такие имена ничего не говорят. Их можно использовать только в том случае, если из контекста кода очевидно, какие данные хранит переменная.
- Договоритесь с вашей командой об используемых терминах. Если посетитель сайта называется «user», тогда мы должны называть связанные с ним переменные currentUser или newUser , а не, к примеру, currentVisitor или newManInTown .
Звучит просто? Действительно, это так, но на практике для создания описательных и кратких имён переменных зачастую требуется подумать. Действуйте.
Повторно использовать или создавать новую переменную?
И последняя заметка. Есть ленивые программисты, которые вместо объявления новых переменных повторно используют существующие.
В результате их переменные похожи на коробки, в которые люди бросают разные предметы, не меняя на них этикетки. Что сейчас находится внутри коробки? Кто знает? Нам необходимо подойти поближе и проверить.
Такие программисты немного экономят на объявлении переменных, но теряют в десять раз больше при отладке.
Дополнительная переменная – это добро, а не зло.
Современные JavaScript-минификаторы и браузеры оптимизируют код достаточно хорошо, поэтому он не создаёт проблем с производительностью. Использование разных переменных для разных значений может даже помочь движку оптимизировать ваш код.
Итого
Мы можем объявить переменные для хранения данных с помощью ключевых слов var , let или const .
- let – это современный способ объявления.
- var – это устаревший способ объявления. Обычно мы вообще не используем его, но мы рассмотрим тонкие отличия от let в главе Устаревшее ключевое слово "var" на случай, если это всё-таки вам понадобится.
- const – похоже на let , но значение переменной не может изменяться.
Переменные должны быть названы таким образом, чтобы мы могли легко понять, что у них внутри.
Задачи
Работа с переменными
важность: 2
- Объявите две переменные: admin и name .
- Запишите строку "Джон" в переменную name .
- Скопируйте значение из переменной name в admin .
- Выведите на экран значение admin , используя функцию alert (должна показать «Джон»).
В коде ниже каждая строка решения соответствует одному элементу в списке задач.
let admin, name; // можно объявить две переменные через запятую name = "Джон"; admin = name; alert( admin ); // "Джон"