Переменные
JavaScript-приложению обычно нужно работать с информацией. Например:
- Интернет-магазин – информация может включать продаваемые товары и корзину покупок.
- Чат – информация может включать пользователей, сообщения и многое другое.
Переменные используются для хранения этой информации.
Переменная
Переменная – это «именованное хранилище» для данных. Мы можем использовать переменные для хранения товаров, посетителей и других данных.
Для создания переменной в JavaScript используйте ключевое слово let .
Приведённая ниже инструкция создаёт (другими словами: объявляет или определяет) переменную с именем «message»:
Теперь можно поместить в неё данные, используя оператор присваивания = :
Строка сохраняется в области памяти, связанной с переменной. Мы можем получить к ней доступ, используя имя переменной:
Для краткости можно совместить объявление переменной и запись данных в одну строку:
Мы также можем объявить несколько переменных в одной строке:
Такой способ может показаться короче, но мы не рекомендуем его. Для лучшей читаемости объявляйте каждую переменную на новой строке.
Многострочный вариант немного длиннее, но легче для чтения:
Некоторые люди также определяют несколько переменных в таком вот многострочном стиле:
…Или даже с запятой в начале строки:
В принципе, все эти варианты работают одинаково. Так что это вопрос личного вкуса и эстетики.
В старых скриптах вы также можете найти другое ключевое слово: var вместо let :
Ключевое слово var – почти то же самое, что и let . Оно объявляет переменную, но немного по-другому, «устаревшим» способом.
Есть тонкие различия между let и var , но они пока не имеют для нас значения. Мы подробно рассмотрим их в главе Устаревшее ключевое слово "var".
Аналогия из жизни
Мы легко поймём концепцию «переменной», если представим её в виде «коробки» для данных с уникальным названием на ней.
Например, переменную message можно представить как коробку с названием "message" и значением "Hello!" внутри:
Мы можем положить любое значение в коробку.
Мы также можем изменить его столько раз, сколько захотим:
При изменении значения старые данные удаляются из переменной:
Мы также можем объявить две переменные и скопировать данные из одной в другую.
Переменная может быть объявлена только один раз.
Повторное объявление той же переменной является ошибкой:
Поэтому следует объявлять переменную только один раз и затем использовать её уже без let .
Примечательно, что существуют функциональные языки программирования, такие как Scala или Erlang, которые запрещают изменять значение переменной.
В таких языках однажды сохранённое «в коробку» значение остаётся там навсегда. Если нам нужно сохранить что-то другое, язык заставляет нас создать новую коробку (объявить новую переменную). Мы не можем использовать старую переменную.
Хотя на первый взгляд это может показаться немного странным, эти языки вполне подходят для серьёзной разработки. Более того, есть такая область, как параллельные вычисления, где это ограничение даёт определённые преимущества. Изучение такого языка (даже если вы не планируете использовать его в ближайшее время) рекомендуется для расширения кругозора.
Имена переменных
В JavaScript есть два ограничения, касающиеся имён переменных:
- Имя переменной должно содержать только буквы, цифры или символы $ и _ .
- Первый символ не должен быть цифрой.
Примеры допустимых имён:
Если имя содержит несколько слов, обычно используется верблюжья нотация, то есть, слова следуют одно за другим, где каждое следующее слово начинается с заглавной буквы: myVeryLongName .
Самое интересное – знак доллара ‘$’ и подчёркивание ‘_’ также можно использовать в названиях. Это обычные символы, как и буквы, без какого-либо особого значения.
Эти имена являются допустимыми:
Примеры неправильных имён переменных:
Переменные с именами apple и APPLE – это две разные переменные.
Можно использовать любой язык, включая кириллицу или даже иероглифы, например:
Технически здесь нет ошибки, такие имена разрешены, но есть международная традиция использовать английский язык в именах переменных. Даже если мы пишем небольшой скрипт, у него может быть долгая жизнь впереди. Людям из других стран, возможно, придётся прочесть его не один раз.
Существует список зарезервированных слов, которые нельзя использовать в качестве имён переменных, потому что они используются самим языком.
Например: let , class , return и function зарезервированы.
Приведённый ниже код даёт синтаксическую ошибку:
Обычно нам нужно определить переменную перед её использованием. Но в старые времена было технически возможно создать переменную простым присвоением значения без использования let . Это все ещё работает, если мы не включаем use strict в наших файлах, чтобы обеспечить совместимость со старыми скриптами.
Это плохая практика, которая приводит к ошибке в строгом режиме:
Константы
Чтобы объявить константную, то есть, неизменяемую переменную, используйте const вместо let :
Переменные, объявленные с помощью const , называются «константами». Их нельзя изменить. Попытка сделать это приведёт к ошибке:
Если программист уверен, что переменная никогда не будет меняться, он может гарантировать это и наглядно донести до каждого, объявив её через const .
Константы в верхнем регистре
Широко распространена практика использования констант в качестве псевдонимов для трудно запоминаемых значений, которые известны до начала исполнения скрипта.
Названия таких констант пишутся с использованием заглавных букв и подчёркивания.
Например, сделаем константы для различных цветов в «шестнадцатеричном формате»:
- COLOR_ORANGE гораздо легче запомнить, чем "#FF7F00" .
- Гораздо легче допустить ошибку при вводе "#FF7F00" , чем при вводе COLOR_ORANGE .
- При чтении кода COLOR_ORANGE намного понятнее, чем #FF7F00 .
Когда мы должны использовать для констант заглавные буквы, а когда называть их нормально? Давайте разберёмся и с этим.
Название «константа» просто означает, что значение переменной никогда не меняется. Но есть константы, которые известны до выполнения (например, шестнадцатеричное значение для красного цвета), а есть константы, которые вычисляются во время выполнения сценария, но не изменяются после их первоначального назначения.
Значение pageLoadTime неизвестно до загрузки страницы, поэтому её имя записано обычными, а не прописными буквами. Но это всё ещё константа, потому что она не изменяется после назначения.
Другими словами, константы с именами, записанными заглавными буквами, используются только как псевдонимы для «жёстко закодированных» значений.
Придумывайте правильные имена
В разговоре о переменных необходимо упомянуть, что есть ещё одна чрезвычайно важная вещь.
Название переменной должно иметь ясный и понятный смысл, говорить о том, какие данные в ней хранятся.
Именование переменных – это один из самых важных и сложных навыков в программировании. Быстрый взгляд на имена переменных может показать, какой код был написан новичком, а какой – опытным разработчиком.
В реальном проекте большая часть времени тратится на изменение и расширение существующей кодовой базы, а не на написание чего-то совершенно нового с нуля. Когда мы возвращаемся к коду после какого-то промежутка времени, гораздо легче найти информацию, которая хорошо размечена. Или, другими словами, когда переменные имеют хорошие имена.
Пожалуйста, потратьте время на обдумывание правильного имени переменной перед её объявлением. Делайте так, и будете вознаграждены.
Несколько хороших правил:
- Используйте легко читаемые имена, такие как userName или shoppingCart .
- Избегайте использования аббревиатур или коротких имён, таких как a , b , c , за исключением тех случаев, когда вы точно знаете, что так нужно.
- Делайте имена максимально описательными и лаконичными. Примеры плохих имён: data и value . Такие имена ничего не говорят. Их можно использовать только в том случае, если из контекста кода очевидно, какие данные хранит переменная.
- Договоритесь с вашей командой об используемых терминах. Если посетитель сайта называется «user», тогда мы должны называть связанные с ним переменные currentUser или newUser , а не, к примеру, currentVisitor или newManInTown .
Звучит просто? Действительно, это так, но на практике для создания описательных и кратких имён переменных зачастую требуется подумать. Действуйте.
И последняя заметка. Есть ленивые программисты, которые вместо объявления новых переменных повторно используют существующие.
В результате их переменные похожи на коробки, в которые люди бросают разные предметы, не меняя на них этикетки. Что сейчас находится внутри коробки? Кто знает? Нам необходимо подойти поближе и проверить.
Такие программисты немного экономят на объявлении переменных, но теряют в десять раз больше при отладке.
Дополнительная переменная – это добро, а не зло.
Современные JavaScript-минификаторы и браузеры оптимизируют код достаточно хорошо, поэтому он не создаёт проблем с производительностью. Использование разных переменных для разных значений может даже помочь движку оптимизировать ваш код.
Итого
Мы можем объявить переменные для хранения данных с помощью ключевых слов var , let или const .
- let – это современный способ объявления.
- var – это устаревший способ объявления. Обычно мы вообще не используем его, но мы рассмотрим тонкие отличия от let в главе Устаревшее ключевое слово "var" на случай, если это всё-таки вам понадобится.
- const – похоже на let , но значение переменной не может изменяться.
Переменные должны быть названы таким образом, чтобы мы могли легко понять, что у них внутри.
Задачи
Работа с переменными
- Объявите две переменные: admin и name .
- Запишите строку "Джон" в переменную name .
- Скопируйте значение из переменной name в admin .
- Выведите на экран значение admin , используя функцию alert (должна показать «Джон»).
В коде ниже каждая строка решения соответствует одному элементу в списке задач.
Var, let и const в JavaScript
![]()
Пока я разбирался что к чему в основах JavaScript, я наткнулся на три способа объявления переменных, а именно var, let и const. В данной статье я попытаюсь обобщить различия этих операторов присваивания.
Чтобы по-настоящему понять разницу между var, let и const, нам необходимо разобраться в следующих понятиях:
- Объявление переменной;
- Инициализация переменной;
- Область видимости;
- Механизм hoisting («поднятие»).
Объявление переменной
Объявление переменной — это процесс введения нового определения в программу или, если быть точнее, в область видимости. В JavaScript переменные изначально приобретают значение undefined, когда мы объявляем ключевое слово var (это автоматически выполняется интерпретатором).
Инициализация переменной
Инициализация переменной — это процесс присваивания значения переменной. Поэтому, когда мы определяем связь между ключевым словом var, интерпретатор присваивает значение undefined.
Область видимости
Область видимости переменной определяет контекст, в котором доступны переменные и функции, на которые можно ссылаться в программе. Область видимости определяет видимость и время жизни переменных и параметров. Если переменной нет в определенной области видимости, то она недоступна для использования. Области видимости также могут располагаться в иерархическом порядке, чтобы дочерние имели доступ к родительским, а не наоборот.
Существует 2 типа области видимости:
- Функциональная область видимости;
- Блочная область видимости.
Функциональная область видимости
Переменные, объявленные внутри функции, входят в область видимости этой функции, а также в область видимости вложенных в нее функций, независимо от блоков.
Блочная область видимости
Переменные, объявленные внутри блока, входят в область видимости только этого блока, а также вложенных в него блоков, но не за пределами блока, даже если это все одна функция. В блоки входят if. else и циклы.
Поднятие
В веб-документации MDN говорится:
«Поднятие — это термин, использование которого вы не найдете ни в одной нормативной документации JavaScript до спецификации языка ES2015. Предполагалось, что поднятие — это обобщенный способ видения того, как работает контекст исполнения (особенно создание и исполнение стадий) в JavaScript. Однако это понятие по началу может сбивать с толку.
Концептуально, например, строгое определение поднятия предполагает, что объявление переменной и функции физически располагается в начале кода, но это не так. Объявления переменной и функции помещаются в память на стадии компиляции, но остаются там, где вы их набрали в своем коде».
Как можно упростить оценку интерпретатора JS для кода выше:
Оператор var объявляет переменную, опционально присваивая ей значение. Любая переменная, объявленная оператором var, имеет функциональную область видимости и идентифицирует объявленные переменные с помощью ключевого слова var. Такие переменные поднятые, а их первоначальное значение — undefined.
Оператор let объявляет локальную переменную. Любая переменная, объявленная с помощью let, имеет блочную область видимости. Значения подняты и не инициализированы.
Связи let создаются сверху области видимости конкретного блока, содержащего определение, часто называемого поднятием. В отличие от переменных, объявленных с помощью var, которые начинаются со значения undefined, переменные let не инициализируются, пока им не присвоится значение. Обращение к переменной до инициализации вызовет Reference Error (ошибка использования несуществующего названия).
const
Оператор const объявляет переменную, почти как let, но у него появляется еще одно свойство. Он не может быть переопределен, то есть после инициализации связей const не может присвоить никакое другое значение.
Следовательно, const должен быть всегда инициализирован при объявлении, иначе возникает ошибка.
Стоит отметить, что когда const связан с объектом, сам объект нельзя изменить, и const будет указывать на тот же самый объект. Однако изменения внутри объекта допустимы.
Один последний факт:
Переменные, объявленные внутри функции без ключевого слова, станут глобальными переменными. Взглянем на это в следующем примере:
Чтобы понять что происходит, нам нужно вернуться назад к понятию поднятия. Обычно при инициализации переменной в нашем коде интерпретатор ищет «поднятые переменные» и затем присваивает или переназначает значение переменной. Однако, когда интерпретатор не может найти переменную внутри функции, он ищет ее среди переменных родительской функции, пока не дойдет до глобальной области видимости.
В нашем случае интерпретатор не найдет ‘isGloballyAvailable’ даже в глобальной области видимости, поэтому он автоматически туда ее добавит.
Это невероятно опасный процесс, которого лучше не допускать. Поэтому имейте в виду, что объявлять переменные без ключевых слов var, let и const нельзя.
Так, когда использовать var, let или const?
ES2015(ES6) представил let и const. Зачем JavaScript разработчикам их вводить? Может, чтобы исправить проблемы, возникающие с var, или для улучшения читабельность кода?
Одна главная проблема с var связана с тем, что он позволяет переназначать переменные в коде, из-за чего не выбрасываются ошибки. Это приводит к различным побочным эффектам в коде.
Распространенное мнение, которое сходится с моим:
Всегда отдавайте предпочтение const, если значение, присвоенное переменной, не изменится. Это подскажет будущим разработчикам, что у переменной неизменное значение.
Руководство по JavaScript, часть 3: переменные, типы данных, выражения, объекты
Сегодня, в третьей части перевода руководства по JavaScript, мы поговорим о разных способах объявления переменных, о типах данных, о выражениях и об особенностях работы с объектами.
Переменные
Переменная представляет собой идентификатор, которому присвоено некое значение. К переменной можно обращаться в программе, работая таким образом с присвоенным ей значением.
Сама по себе переменная в JavaScript не содержит информацию о типе значений, которые будут в ней храниться. Это означает, что записав в переменную, например, строку, позже в неё можно записать число. Такая операция ошибки в программе не вызовет. Именно поэтому JavaScript иногда называют «нетипизированным» языком.
Прежде чем использовать переменную, её нужно объявить с использованием ключевого слова var или let . Если речь идёт о константе, применяется ключевое слово const . Объявить переменную и присвоить ей некое значение можно и не используя эти ключевые слова, но делать так не рекомендуется.
▍Ключевое слово var
До появления стандарта ES2015 использование ключевого слова var было единственным способом объявления переменных.
Если в этой конструкции опустить var , то значение будет назначено необъявленной переменной. Результат этой операции зависит от того, в каком режиме выполняется программа.
Так, если включён так называемый строгий режим (strict mode), подобное вызовет ошибку. Если строгий режим не включён, произойдёт неявное объявление переменной и она будет назначена глобальному объекту. В частности, это означает, что переменная, неявно объявленная таким образом в некоей функции, окажется доступной и после того, как функция завершит работу. Обычно же ожидается, что переменные, объявляемые в функциях, не «выходят» за их пределы. Выглядит это так:
В консоль попадёт 1 , такого поведения от программы обычно никто не ждёт, выражение bNotVar = 1 выглядит не как попытка объявления и инициализации переменной, а как попытка обратиться к переменной, находящейся во внешней по отношению к функции области видимости (это — вполне нормально). Как результат, неявное объявление переменных сбивает с толку того, кто читает код и может приводить к неожиданному поведению программ. Позже мы поговорим и о функциях, и об областях видимости, пока же постарайтесь всегда, когда смысл некоего выражения заключается в объявлении переменной, пользоваться специализированными ключевыми словами. Если в этом примере тело функции переписать в виде var bNotVar = 1 , то попытка запустить вышеприведённый фрагмент кода приведёт к появлению сообщения об ошибке (его можно увидеть в консоли браузера).
Выглядеть оно, например, может так: Uncaught ReferenceError: bNotVar is not defined . Смысл его сводится к тому, что программа не может работать с несуществующей переменной. Гораздо лучше, при первом запуске программы, увидеть такое сообщение об ошибке, чем писать непонятный код, который способен неожиданно себя вести.
Если, при объявлении переменной, её не инициализируют, не присваивают ей какого-либо значения, ей автоматически будет присвоено значение undefined .
Переменные, объявленные с помощью ключевого слова var , можно многократно объявлять снова, назначая им новые значения (но это может запутать того, кто читает код).
В одном выражении можно объявить несколько переменных:
Областью видимости переменной (scope) называют участок программы, в котором доступна (видима) эта переменная.
Переменная, инициализированная с помощью ключевого слова var за пределами какой-либо функции, назначается глобальному объекту. Она имеет глобальную область видимости и доступна из любого места программы. Если переменная объявлена с использованием ключевого слова var внутри функции, то она видна только внутри этой функции, являясь для неё локальной переменной.
Если в функции, с использованием var , объявлена переменная, имя которой совпадает с именем некоей переменной из глобальной области видимости, она «перекроет» глобальную переменную. То есть, при обращении к такой переменной внутри функции будет использоваться именно её локальный вариант.
Важно понимать, что блоки (области кода, заключённые в фигурные скобки) не создают новых областей видимости. Новая область видимости создаётся при вызове функции. Ключевое слово var имеет так называемую функциональную область видимости, а не блочную.
Если в коде функции объявлена некая переменная, она видна всему коду функции. Даже если переменная объявлена с помощью var в конце кода функции, обратиться к ней можно и в начале кода, так как в JavaScript работает механизм поднятия переменных (hoisting). Этот механизм «поднимает» объявления переменных, но не операции их инициализации. Это может стать источником путаницы, поэтому возьмите себе за правило объявлять переменные в начале функции.
▍Ключевое слово let
Ключевое слово let появилось в ES2015, его, упрощённо, можно назвать «блочной» версией var . Область видимости переменных, объявленных с помощью ключевого слова let , ограничивается блоком, оператором или выражением, в котором оно объявлено, а также вложенными блоками.
Если само слово «let» кажется не очень понятным, можно представить, что вместо него используется слово «пусть». Тогда выражение let color = ‘red’ можно перевести на английский так: «let the color be red», а на русский — так: «пусть цвет будет красным».
При использовании ключевого слова let можно избавиться от неоднозначностей, сопутствующих ключевому слову var (например, не удастся два раза, используя let , объявить одну и ту же переменную). Использование let за пределами функции, скажем, при инициализации циклов, не приводит к созданию глобальных переменных.
Например, такой код вызовет ошибку:
Если же, при инициализации цикла, счётчик i будет объявлен с использованием ключевого слова var , то i будет доступно и за пределами цикла, после того, как он завершит работу.
В наши дни, при разработке JS-программ на основе современных стандартов, вполне можно полностью отказаться от var и использовать только ключевые слова let и const .
▍Ключевое слово const
Значения переменных, объявленных с использованием ключевых слов var или let , могут быть перезаписаны. Если же вместо этих ключевых слов используется const , то объявленной и инициализированной с его помощью константе новое значение присвоить нельзя.
В данном примере константе a нельзя присвоить новое значение. Но надо отметить, что если a — это не примитивное значение, наподобие числа, а объект, использование ключевого слова const не защищает этот объект от изменений.
Когда говорят, что в переменную записан объект, на самом деле имеют в виду то, что в переменной хранится ссылка на объект. Эту вот ссылку изменить не удастся, а сам объект, к которому ведёт ссылка, можно будет изменить.
Ключевое слово const не делает объекты иммутабельными. Оно просто защищает от изменений ссылки на них, записанные в соответствующие константы. Вот как это выглядит:
В константу obj , при инициализации, записывается новый пустой объект. Попытка обращения к его свойству a , несуществующему, ошибки не вызывает. В консоль попадает undefined . После этого мы добавляем в объект новое свойство и снова пытаемся обратиться к нему. В этот раз в консоль попадает значение этого свойства — 1 . Если раскомментировать последнюю строку примера, то попытка выполнения этого кода приведёт к ошибке.
Ключевое слово const очень похоже на let , в частности, оно обладает блочной областью видимости.
В современных условиях вполне допустимо использовать для объявления всех сущностей, значения которых менять не планируется, ключевое слово const , прибегая к let только в особых случаях. Почему? Всё дело в том, что лучше всего стремиться к использованию как можно более простых из доступных конструкций для того, чтобы не усложнять программы и избегать ошибок.
Типы данных
JavaScript иногда называют «нетипизированным» языком, но это не соответствует реальному положению дел. В переменные, и правда, можно записывать значения разных типов, но типы данных в JavaScript, всё-таки, есть. В частности, речь идёт о примитивных и об объектных типах данных.
Для того чтобы определить тип данных некоего значения, можно воспользоваться оператором typeof . Он возвращает строку, указывающую тип операнда.
▍Примитивные типы данных
Вот список примитивных типов данных JavaScript:
- number (число)
- string (строка)
- boolean (логическое значение)
- null (специальное значение null )
- undefined (специальное значение undefined )
- symbol (символ, используется в особых случаях, появился в ES6)
Поговорим о наиболее часто используемых типах данных из этого списка.
Тип number
Значения типа number в JavaScript представлены в виде 64-битных чисел двойной точности с плавающей запятой.
В коде числовые литералы представлены в виде целых и дробных чисел в десятичной системе счисления. Для записи чисел можно использовать и другие способы. Например, если в начале числового литерала имеется префикс 0x — он воспринимается как число, записанное в шестнадцатеричной системе счисления. Числа можно записывать и в экспоненциальном представлении (в таких числах можно найти букву e ).
Вот примеры записи целых чисел:
Вот дробные числа.
Числовые литералы (такое поведение характерно и для некоторых других примитивных типов), при попытке обращения к ним как к объектам, автоматически, на время выполнения операции, преобразуются в соответствующие объекты, которые называют «объектными обёртками». В данном случае речь идёт об объектной обёртке Number .
Вот, например, как выглядит попытка обратиться к переменной a , в которую записан числовой литерал, как к объекту, в консоли Google Chrome.

Подсказка по объектной обёртке Number
Если, например, воспользоваться методом toString() объекта типа Number , он возвратит строковое представление числа. Выглядит соответствующая команда, которую можно выполнить в консоли браузера (да и в обычном коде) так:
Обратите внимание на двойные скобки после имени метода. Если их не поставить, система не выдаст ошибку, но, вместо ожидаемого вывода, в консоли окажется нечто, совсем не похожее на строковое представление числа 5.
Глобальный объект Number можно использовать в виде конструктора, создавая с его помощью новые числа (правда, в таком виде его практически никогда не используют), им можно пользоваться и как самостоятельной сущностью, не создавая его экземпляры (то есть — некие числа, представляемые с его помощью). Например, его свойство Number.MAX_VALUE содержит максимальное числовое значение, представимое в JavaScript.
Тип string
Значения типа string представляют собой последовательности символов. Такие значения задают в виде строковых литералов, заключённых в одинарные или двойные кавычки.
Строковые значения можно разбивать на несколько частей, используя символ обратной косой черты (backslash).
Строка может содержать так называемые escape-последовательности, интерпретируемые при выводе строки в консоль. Например, последовательность \n означает символ перевода строки. Символ обратной косой черты можно использовать и для того, чтобы добавлять кавычки в строки, заключённые в такие же кавычки. Экранирование символа кавычки с помощью \ приводит к тому, что система не воспринимает его как специальный символ.
Строки можно конкатенировать с использованием оператора + .
Шаблонные литералы
В ES2015 появились так называемые шаблонные литералы, или шаблонные строки. Они представляют собой строки, заключённые в обратные кавычки ( ` ) и обладают некоторыми интересными свойствами.
Например, в шаблонные литералы можно подставлять некие значения, являющиеся результатом вычисления JavaScript-выражений.
Использование обратных кавычек упрощает многострочную запись строковых литералов:
Тип boolean
В JavaScript есть пара зарезервированных слов, использующихся при работе с логическими значениями — это true (истина), и false (ложь). Операции сравнения, например, такие, как == , === , < , > , возвращают true или false .
Логические выражения используются в конструкциях наподобие if и while , помогая управлять ходом выполнения программы.
При этом надо отметить, что там, где ожидается значение true или false , можно использовать и другие значения, которые автоматически расцениваются языком как истинные (truthy) или ложные (falsy).
В частности, ложными значениями являются следующие:
Остальные значения являются истинными.
Тип null
В JavaScript имеется специальное значение null , которое указывает на отсутствие значения. Подобные значения используются и в других языках.
Тип undefined
Значение undefined , записанное в некую переменную, указывает на то, что эта переменная не инициализирована и значение для неё отсутствует.
Это значение автоматически возвращается из функций, результат работы которых не возвращается явно, с использованием ключевого слова return . Если функция принимает некий параметр, который, при её вызове, не указан, он также устанавливается в undefined .
Для того чтобы проверить значение на undefined , можно воспользоваться следующей конструкцией.
▍Объекты
Все значения, не являющиеся примитивными, имеют объектный тип. Речь идёт о функциях, массивах, о том, что мы называем «объектами», и о многих других сущностях. В основе всех этих типов данных лежит тип object , и они, хотя и во многом друг от друга отличаются, имеют и много общего.
Выражения
Выражения — это фрагменты кода, которые можно обработать и получить на основе проведённых вычислений некое значение. В JavaScript существует несколько категорий выражений.
Арифметические выражения
В эту категорию попадают выражения, результатом вычисления которых являются числа.
Строковые выражения
Результатом вычисления таких выражений являются строки.
Первичные выражения
В эту категорию попадают литералы, константы, ссылки на идентификаторы.
Сюда же можно отнести и некоторые ключевые слова и конструкции JavaScript.
Выражения инициализации массивов и объектов
Логические выражения
В логических выражениях используются логические операторы, результатом их вычисления оказываются логические значения.
Выражения доступа к свойствам
Эти выражения позволяют обращаться к свойствам и методам объектов.
Выражения создания объектов
Выражения объявления функций
Выражения вызова
Такие выражения используются для вызова функций или методов объектов.
Работа с объектами
Выше мы уже сталкивались с объектами, говоря об объектных литералах, о вызове их методов, о доступе к их свойствам. Здесь мы поговорим об объектах подробнее, в частности, рассмотрим механизм прототипного наследования и использование ключевого слова class .
▍Прототипное наследование
JavaScript выделяется среди современных языков программирования тем, что поддерживает прототипное наследование. Большинство же объектно-ориентированных языков используют модель наследования, основанную на классах.
У каждого JavaScript-объекта есть особое свойство ( __proto__ ), которое указывает на другой объект, являющийся его прототипом. Объект наследует свойства и методы прототипа.
Предположим, у нас имеется объект, созданный с помощью объектного литерала.
Или мы создали объект, воспользовавшись конструктором Object .
В любом из этих случаев прототипом объекта car будет Object.prototype .
Если создать массив, который тоже является объектом, его прототипом будет объект Array.prototype .
Проверить это можно следующим образом.
Здесь мы пользовались свойством __proto__ , оно не обязательно должно быть доступно разработчику, но обычно обращаться к нему можно. Надо отметить, что более надёжным способом получить прототип объекта является использование метода getPrototypeOf() глобального объекта Object .
Все свойства и методы прототипа доступны объекту, имеющему этот прототип. Вот, например, как выглядит их список для массива.

Подсказка по массиву
Базовым прототипом для всех объектов является Object.prototype .
У Object.prototype прототипа нет.
То, что мы видели выше, является примером цепочки прототипов.
При попытке обращения к свойству или методу объекта, если такого свойства или метода у самого объекта нет, их поиск выполняется в его прототипе, потом — в прототипе прототипа, и так — до тех пор, пока искомое будет найдено, или до тех пор, пока цепочка прототипов не кончится.
Помимо создания объектов с использованием оператора new и применения объектных литералов или литералов массивов, создать экземпляр объекта можно с помощью метода Object.create() . Первый аргумент, передаваемый этому методу, представляет собой объект, который станет прототипом создаваемого с его помощью объекта.
Проверить, входит ли некий объект в цепочку прототипов другого объекта, можно с использованием метода isPrototypeOf() .
Функции-конструкторы
Выше мы создавали новые объекты, пользуясь уже имеющимися в языке функциями-конструкторами (при их вызове используется ключевое слово new ). Такие функции можно создавать и самостоятельно. Рассмотрим пример.
Здесь мы создаём функцию-конструктор. При её вызове создаётся новый объект, на который указывает ключевое слово this в теле конструктора. Мы добавляем в этот объект свойство name и записываем в него то, что передано конструктору. Этот объект возвращается из конструктора автоматически. С помощью функции-конструктора можно создать множество объектов, свойства name которых будут содержать то, что передано при их создании конструктору.
После создания конструктора мы добавляем в его прототип функцию, которая будет выводить в консоль значение свойства name объекта, созданного с помощью этой функции. Все объекты, созданные с помощью этого конструктора, будут иметь один и тот же прототип, а значит и пользоваться одной и той же функцией hello() . Это несложно проверить, создав ещё один объект типа Person и сравнив его функцию hello() с функцией уже имеющегося в примере объекта (имя функции в таком случае записывают без скобок).
▍Классы
В стандарте ES6 в JavaScript пришло такое понятие как «класс».
До этого в JavaScript можно было пользоваться лишь вышеописанным механизмом прототипного наследования. Этот механизм непривычно выглядел для программистов, пришедших в JS из других языков. Поэтому в языке и появились классы, которые, по сути, являются «синтаксическим сахаром» для прототипного механизма наследования. То есть, и объекты, созданные традиционным способом, и объекты, созданные с использованием классов, имеют прототипы.
Объявление класса
Вот как выглядит объявление класса.
У класса есть идентификатор, который можно использовать для создания новых объектов с применением конструкции new ClassIdentifier() .
При создании нового объекта вызывается метод constructor , ему передаются параметры.
В классе можно объявлять методы. В нашем случае hello() — это метод, который могут вызывать все объекты, созданные на основе класса. Вот как выглядит создание нового объекта с использованием класса Person .
Наследование, основанное на классах
Классы могут расширять другие классы. Объекты, созданные на основе таких классов, будут наследовать и методы исходного класса, и методы, заданные в расширенном классе.
Если класс, расширяющий другой класс (наследник этого класса) имеет метод, имя которого совпадает с тем, который есть у класса-родителя, этот метод имеет преимущество перед исходным.
При вызове метода hello() в вышеприведённом примере будет возвращена строка Hello, I am Flavio. I am a programmer .
В классах не предусмотрено наличие переменных (свойств), свойства создаваемых с помощью классов объектов нужно настраивать в конструкторе.
Внутри класса можно обращаться к родительскому классу с использованием ключевого слова super .
Статические методы
Методы, описываемые в классе, можно вызывать, обращаясь к объектам, созданным на основе этого класса, но не к самому классу. Статические ( static ) методы можно вызывать, обращаясь непосредственно к классу.
Приватные методы
В JavaScript нет встроенного механизма, который позволяет объявлять приватные (частные, закрытые) методы. Это ограничение можно обойти, например, с использованием замыканий.
Геттеры и сеттеры
В классе можно описывать методы, предваряя их ключевыми словами get или set . Это позволяет создавать так называемые геттеры и сеттеры — функции, которые используются для управления доступом к свойствам объектов, созданных на основе класса. Геттер вызывается при попытке чтения значения псевдо-свойства, а сеттер — при попытке записи в него нового значения.
Итоги
В этом материале мы поговорили о переменных, о типах данных, о выражениях и о работе с объектами в JavaScript. Темой нашего следующего материала будут функции.
Уважаемые читатели! Если вы уже давно пишете на JS, просим рассказать о том, как вы относитесь к появлению в языке ключевого слова class.
Выражения, переменные и типы данных в JavaScript

В этой статье мы напишем первую простую программу на JavaScript, разберём из чего она состоит и как работает. После чего изучим выражения, переменные, ключевые слова для их объявления, типы данных, что такое динамическая типизация и что делает оператор typeof .
Первая программа
Изучение JavaScript начнём с создания простой программы, состоящей из одной строчки, которая будет выводить в консоль браузера сообщение «Hello, World!»:
Полный текст HTML документа:
Для его создания можно воспользоваться любым текстовым редактором, например, Visual Studio Code.
Для этого откройте текстовый редактор, вставьте в него этот код и сохраните его в файл с расширением html (например, «index.html»).
После этого откройте его в браузере, например, Google Chrome. Далее перейдите в «Инструменты разработчика», а в них на вкладку «Console»:

Здесь мы увидим вывод нашего сообщения «Hello, World!».
Программа на JavaScript находится между открывающим и закрывающим тегом script . Как уже было отмечено выше эта программа состоит всего из одной строчки кода:
Этот код выполняет очень простое действие: выводит сообщение, указанное в круглых скобках в консоль .
Чтобы понять как эта строчка работает, рассмотрим из чего она состоит:
- console – это объект . Объект в JavaScript – это набор свойств. Каждое свойство состоит из имени и значения («имя: значение»), имена также ещё называют ключами.
- log – это одно из свойств объекта console , а точнее его метод . Т.к. в качестве его значения выступает функция .
- . (точка) – это оператор, который мы используем для доступа к свойствам и методам объекта. В данном случае мы с помощью точки получаем доступ к методу log объекта console .
- () (скобки) – это часть синтаксиса JavaScript, с помощью которого в данном случае мы вызываем функцию log , которая является методом объекта console .
- ‘Hello, World!’ – аргумент типа String (строка), т.е. значение, которое мы передаём в метод log() .
Таким образом, эта строчка console.log(‘Hello, World!’); вызывает метод log() и передаёт ему в качестве аргумента значение ‘Hello, World!’ . log() – это метод объекта console и поэтому чтобы к нему обратиться мы используем точку.
В этом примере мы познакомились с одними из ключевых понятий JavaScript: объектом и функцией. Здесь объектом является console , а функцией — метод log() .
В заключении отметим, что строка console.log(‘Hello, World!’) является выражением.
Выражения
Выражение – это тоже одно из ключевых понятий в JavaScript. Оно представляет собой некоторый кусок кода, который всегда возвращает значение.
Если вернутся к предыдущему примеру, то console.log(‘Hello, World!’) как мы уже отметили выше является выражением, т.к. возвращает значение:
В качестве значения данное выражение возвращает undefined . В этом легко убедиться если его обернуть в ещё одну конструкцию console.log() :
- ‘Alexander’ – это выражение, которое представляет собой строку; результатом этого выражения будет эта же строка;
- 7 + 3 – это выражение, в котором используется оператор + ; результатом этого выражения будет число 10 ;
- ‘Alexander’ + ‘ ‘ + ‘Maltsev’ – результатом этого выражения будет новая строка ‘Alexander Maltsev’ ;
- name = ‘Tim’ – это выражение, в котором используется оператор присваивания; здесь переменной name присваивается значение ‘Tim’ ; результатом этого выражения будет строка ‘Tim’ , т.е. то значение, которое мы присваиваем переменной;
- index++ – здесь используется оператор ++ , который увеличивает значение переменной на 1; результатом этого выражения будет значение переменной index , увеличенное на 1;
- 2 > 3 || 2 > 1 – это выражение, в котором используются несколько операторов; оно возвращает значение true ;
- sum(3, 5) – вызов функции также является выражением, т.к. функция всегда возвращает какое-либо значение.
Некоторые примеры этих выражений имеют side effects (побочные действия). Т.е. они не только возвращают значение, но выполняют также некоторые дополнительные действия.
Например, выражение name = ‘Tim’ не только возвращает значение ‘Tim’ , но также выполняет присвоение переменной name значения ‘Tim’ .
Если взять выражение index++ , то оно тоже кроме возвращения значения ещё увеличивает значение переменной index на единицу.
Если внутри функции будут выполняться некоторые другие действия кроме возврата значения, то это выражение также будет иметь side effects.
Переменные
Переменная – это именованный участок памяти для хранения данных. Они используются когда необходимо сохранить некоторое значение, чтобы к нему можно было обратиться позже.
Представить переменную можно как коробку, на которой написано некоторое название (имя переменной). В коробку мы можем положить некоторое значение.

В дальнейшем мы можем обратиться к этому значению, в данном случае по имени num и выполнить с ним какие-либо действия. Затем мы можем поместить в переменную другое значение. Но в процессе выполнения программы переменная в определённый момент времени всегда имеет какое-то одно определённое значение.
Именование переменных
Имя переменной можно составлять из букв, цифр и символов $ и _ . При этом первый символ переменной не должен быть цифрой. Кроме этого, в качестве имени переменной нельзя использовать зарезервированные слова JavaScript.
Регистр букв в имени переменной имеет значение. Т.е., например, phone и Phone – это две разные переменные.
Несмотря на то, что вы можете выбирать любые названия для переменных, хорошей практикой является придерживаться следующих рекомендаций при составлении имен:
- PascalCase – для именования типов и классов;
- SELECTOR_ITEM – для именования констант (значения которых известно до запуска программы и не меняются на протяжении её выполнения);
- camelCase – во всех остальных случаях.
PascalCase – имя переменной всегда начинается с заглавной буквы. Другие слова, которые являются частью названия переменной тоже начинаются с большой буквы. Не допускается пробелов, тире, т.е. всё пишется слитно.
Именование констант (например, SELECTOR_ITEM ) осуществляется прописными буквами и нижнего подчеркивания для разделения слов.
camelCase – тоже самое что PascalCase за исключением того, что первая буква пишется в нижнем регистре.
Кроме этого, желательно также давать именам четкие названия, чтобы было очень просто понять, что хранится в такой переменной.
Объявление переменных
В JavaScript доступно 3 ключевых слова, с помощью которых можно объявить переменные: let , const и var .
Ключевые слова let и const появились в языке с приходом ECMAScript 6, который вышел в 2015 году. var присутствовало в языке JavaScript с самого начала и до ECMAScript 6 использовалось только оно.
В настоящее время не рекомендуется использовать ключевое слово var , а только let и const .
Пример объявление переменной с названием email :
Перед названием переменной расположено ключевое слово let . Это слово дает инструкцию интерпретатору JavaScript создать новую переменную с именем email .
При создании переменной ей можно сразу же присвоить некоторое значение. Эту операцию называют инициализацией . Выполняется присвоение значения только что объявленной переменной с помощью оператора = .
Присвоим переменной, объявленной до этого новое значение:
Для того чтобы получить значение переменной к ней нужно просто обратиться по имени.
Переменная, которая объявлена без инициализации имеет по умолчанию значение undefined .
С помощью одного ключевого слова можно объявить сразу несколько переменных:
Отделение друг от друга осуществляется посредством запятой.
Отличие let от const
Основное отличие let от const заключаются в том, что значения переменным, объявленных с помощью ключевого слова let , можно переприсваивать, т.е. задавать им новые значения.
Если вы используете const , то необходимо при объявлении переменной сразу же присвоить ей значение:
Если это не сделать, то получите ошибку:
При попытке присвоить новое значение, вы также получите ошибку:
Таким образом, переменной, объявленной с помощью const нельзя присваивать новые значения. Это основное отличие let от const .
Если в коде вы не планируете переменной присваивать новые значения, то тогда рекомендуется её объявлять с помощью const .
Также необходимо отметить, что если вы попытаетесь получить доступ к переменной, которая ещё не объявлена, то получите ошибку:
Кроме этого, получите ошибку, если попытаетесь объявить переменную ещё один раз в её области видимости:
При работе с const имеется один очень интересный момент. Если присвоить переменной значение ссылочного типа, то вы не сможете изменить только саму ссылку на этот объект. Но при этом сам объект будет доступен для изменения.
Изменить объект, ссылка на который содержится в переменной, объявленной с помощью const можно:
Ключевое слово var
Как уже было отмечено выше, использовать var для объявления переменных сейчас не рекомендуется.
Отличия var от let и const :
1. var в отличие от let и const имеет функциональную область видимости, т.е. если её объявить внутри функции, то она будет видна во всем коде этой функции. При этом видимость let и const ограничена блоком, т.е. они видны только в пределах фигурных скобок { . } .
2. Переменные, объявленные с помощью var поднимаются к началу текущего контекста. Называется это hoisting. К такой переменной можно обратиться до её объявления:
Кроме этого, мы даже можем присвоить значение переменной до её объявления:
В случае с let или const такое не получится, т.к. её использовать можно только после объявления.
3. Если строгий режим не используется, то создать переменную с начальным значением можно без ключевого слова var :
Создавать переменные без var не рекомендуется.
В строгом режиме мы получим ошибку:
Типы данных
Значение в JavaScript имеют определённый тип. Когда переменной мы присваиваем значение, она соответственно тоже принимает этот тип.
Все типы данных в JavaScript можно разделить на примитивные и ссылочный.
В JavaScript выделяют 7 примитивных типов:
- number (обычные числа);
- bigint (большие целые числа);
- string (строки);
- boolean (логический) – имеет всего два значения: true и false ;
- null – имеет одно значения: null ;
- undefined – имеет одно значения: undefined ;
- symbol (символ) – для создания уникальных значений;
Когда вы присваиваете переменным значения примитивных типов, то они будут непосредственно содержать значения в памяти компьютера, т.е. явно.
В этом примере мы присвоили переменной coordY значение, находящееся в coordX . coordY будет после этого непосредственно содержать это значение в памяти.
Если мы переопределим значение переменной coordX , то значение coordY не изменится. Потому что значения примитивных типов хранятся непосредственно в переменных. Т.е. переменная coordY в таком случае получит собственную копию этого значения.
Ссылочный тип в JavaScript только один – это object (объект). Объект – это одно из ключевых понятий JavaScript. Т.к. в этом языке всё практически является объектами. Функция, массив, дата и т.д. – это объекты. Даже примитивные типы данных ведут себя как объекты, хотя ими не являются.
1. Object (объект)
Объект – это набор свойств «имя: значение». Имена часто также называют ключами.
Пример объекта записанного с помощью литерального синтаксиса, т.е. фигурных скобок:
В этом примере свойства firstName , lastName и age содержат значения примитивных типов данных. Значение свойства pets – объект. Такие объекты называются вложенными. У него содержатся свои свойства с соответствующими значениями.
Свойство getFullName содержит в качестве значения функцию. Такие свойства в JavaScript называются методами.
Когда мы присваиваем такой объект переменной, в ней будет храниться только ссылка (например, 0xD30F ) на этот объект. А сам объект будет хранится в области памяти на которую указывает эта ссылка.
Если некоторой переменной присвоить значение переменой person , то она будет тоже содержать ссылку на этот объект:
Таким образом, у нас получатся две переменные, которые ссылаются на один и тот же объект.
Если добавим новое свойство в объект с помощью переменной myPerson , то мы увидим изменение в этом объекте и посредством переменной person , т.к. они указывают на один и тот же объект в памяти:
Для обращения к свойству hobbies в этом примере мы использовали точку. Кроме точечной записи (dot notation), вы можете также работать со свойствами объектами используя квадратные скобки:
2. Number (число)
Числовой тип в JavaScript является универсальным. Он используется для представления как целых, так и чисел с плавающей точкой.
Формат представления чисел в JavaScript осуществляется в соответствии со стандартом IEEE 754-2008.
Целые числа в JavaScript можно задавать не только в десятичной системе счисления, но и в восьмеричной (0) или шестнадцатеричной системе счисления (0x) с использованием префиксов, указанных в круглых скобках:
Записывать числа также можно в экспоненциальной форме :
Числовой тип данных кроме чисел содержит ещё специальные числовые значения :
- Infinity (положительная бесконечность);
- -Infinity (отрицательная бесконечность);
- NaN (Not a Number – не число).
Специальное значения Infinity означает очень большое положительное число, т.е. число, которое не может быть представлено в JavaScript по причине того, что оно слишком велико.
Специальные значения -Infinity означает, наоборот, очень большое отрицательное число, т.е. число, которое не может быть представлено JavaScript по причине того, что оно тоже слишком велико.
Пример выражений, в результате вычисления которых будет возвращены специальные числовые значения :
Значение NaN возвращается в результате выполнения математических операций, которые JavaScript не может вычислить.
При этом очень интересным является то, что значение NaN в JavaScript не равно ничему включая себя.
3. BigInt (большое целое число)
BigInt – это числовой тип, который предоставляет возможность работать с большими целыми числами. Появился этот тип в спецификации ECMAScript 2020 (11 редакции).
Примитив bigint создается путём добавления n в конец числа:
4. String (строка)
String (строка) – это тип данных, который используется в JavaScript для представления текста.
Строка JavaScript может состоять из 0 или большего количества символов.
В качестве формата строки в JavaScript всегда используется кодировка Unicode.
Создание строки (литерала строки) выполняется посредством заключения текста в одинарные или двойные кавычки .
В JavaScript нет разницы между одинарными и двойными кавычками.
Но, в некоторых случаях есть смысл использовать именно одинарные кавычки, а не двойные и наоборот.
Например, когда строка содержит двойные кавычки, её более удобно заключить в одинарные. Это избавит от необходимости экранирования в ней двойных кавычек.
Строка в JavaScript может содержать специальные символы. Например, (перевод строки), (табуляция), (возврат каретки) и др.
Со строками можно производить операцию сложения (объединения) или, другими словами, конкатенацию. Для этого используется оператор + . Смысл данной операции заключается в присоединении второй строки к концу первой.
5. Boolean (логический тип данных)
Boolean – примитивный тип данных, который имеет всего два значения: true (истина) и false (ложь).
6. Тип null
null – тип данных, который имеет одно значение: null .
Он используется, когда вы хотите явно указать, что на данном этапе у переменной нет значения, т.е. оно отсутствует.
7. Тип undefined
undefined — тип данных, который имеет одно значение: undefined . Такое значение подразумевает, что значение у той или иной переменной нет, т.е. оно не определено.
Такое значение содержит объявленная переменная, которой ещё не присвоено значение.
Значение undefined также возвращается при доступе к свойству объекта, которого у него нет:
Также функция которая явно не возвращает значение:
Аналогично будет использование оператора return без указания значения:
Разница между null и undefined заключается в том, что значение null мы присваиваем переменной сами.
8. Symbol (символ)
Symbol (символ) предназначен для создания уникальных идентификаторов. Появился этот тип данных в ECMAScript 2015 (6 редакции). Создание символа выполняется с помощью функции Symbol() :
Эта функция всегда возвращает уникальное значение символа. В круглых скобках при необходимости можно указать описание символа, которое также называется его именем. В этом примере в качестве него задана строка ‘id’ .
Символы в основном применяются для создания скрытых свойств объекта, а также для изменения встроенного поведения объектов с использованием системных символов.
Динамическая типизация
JavaScript является языком с динамической типизацией. Это означает, что при объявлении переменной ей не нужно указывать тип данных, который она может принимать. Вы должны просто задекларировать переменную с помощью ключевого слова let или const .
Таким образом, вы сначала можете присвоить переменной значение с одним типом данных, а позже переприсвоить ей значение, имеющее другой тип данных.
Например, присвоим одной и той же переменной значения разных типов:
Динамическая типизация имеет преимущества, так и недостатки:
В этом примере мы объявили функцию с помощью ключевого слова function . sum — это название функции. Когда мы первый раз вызывали функцию, переменная sum содержала её. После этого мы присвоили переменной число 4 . Теперь когда попытаемся вызвать функцию ещё раз, мы получим ошибку. Т.к. переменная sum на данном этапе содержит просто число.
Чтобы таких ошибок было меньше в коде, рекомендуется где это возможно использовать ключевое слово const :
В этом примере функция также содержится в переменной, но в объявленной с помощью const . А так как переменная объявлена с помощью const , то мы не можем ей присвоить новое значение, в данном случае число 4 .
Оператор typeof
Оператор typeof позволяет определить тип того или иного значения. При этом у него имеется два синтаксиса, с круглыми скобками и без них:
В качестве результата он возвращает строку, которая будет показывать тип этого значения:
(1) — При получении типа данных для значения null , оператор typeof возвращает object . Это ошибка, которая присутствует в языке, начиная с его первой реализации. Она не была исправлена в целях сохранения совместимости и это необходимо учитывать, при написании сценариев. null — это примитивный тип данных, он не является объектом.
(2) — Очень удобно, что typeof выделяет функции отдельно. Это позволяет нам очень просто проверить является ли указанная переменная функцией. Но функции в JavaScript являются объектами:
Оператор typeof очень часто используется когда нужно узнать есть ли значение у переменной:
Также typeof применяется когда вы не уверены какой тип у переменной и вам нужно его проверить перед тем как выполнить какие-то действия:
В этом примере мы будем прибавлять к sum значение переменной item только если она является числом, т.е. имеет тип number .