Javascript задать тип переменной. Как правильно проверить тип переменной в JavaScript. JavaScript типы являются динамическими

Переменные JavaScript могут хранить данные самых разных типов - числа, строки, объекты и другие:

Var length = 16; // Число var lastName = "Сидоров"; // Строка var x = {firstName:"Иван", lastName:"Иванов"}; // Объект

Концепция типов данных

В программировании типизация данных является очень важной концепцией.

Чтобы можно было оперировать переменными, крайне важно знать об их типах.

Без типов данных компьютер не будет знать как безопасно вычислить, например, такое выражение:

Var x = 16 + "Volvo";

Имеет ли смысл добавлять к строке "Volvo" число 16? Это приведет к ошибке или какому-либо разумному результату?

JavaScript будет интерпретировать приведенный выше пример следующим образом:

Var x = "16" + "Volvo";

Внимание! При сложении числа и строки JavaScript будет воспринимать число как строку.

JavaScript вычисляет выражения слева направо. Таким образом, разные последовательности могут привести к разным результатам:

JavaScript: var x = 16 + 4 + "Volvo"; Результат: 20Volvo JavaScript: var x = "Volvo" + 16 + 4; Результат: Volvo164

В первом примере JavaScript воспринимает 16 и 4 как числа, пока не достигнет строки "Volvo".

Во втором примере, так как первый операнд - строка, все последующие операнды также считаются строками.

JavaScript типы являются динамическими

В JavaScript все типы данных являются динамическими. Это означает, что одна и та же переменная может использоваться для хранения данных разных типов:

Var x; // x имеет тип undefined x = 5; // теперь x - число x = "John"; // теперь x - строка

Строки в JavaScript

Строка (или текстовая строка) это последовательность символов, например, "Иван Петров".

Строки должны записываться внутри кавычек. Это могут быть двойные или одинарные кавычки:

Var carName = "Volvo XC60"; // Используются двойные кавычки var carName = "Volvo XC60"; // Используются одинарные кавычки

Внутри строки можно использовать кавычки только в том случае, если они отличаются от кавычек, в которые заключена строка:

Var answer = "It"s alright"; // Одинарные кавычки внутри двойных var answer = "He is called "Johnny""; // Одинарные кавычки внутри двойных var answer = "He is called "Johnny""; // Двойные кавычки внутри одинарных

Числа в JavaScript

В JavaScript существует только один тип числовых данных.

Числа могут записываться как с десятичной точкой, так и без нее:

Var x1 = 34.00; // С десятичной точкой var x2 = 34; // Без десятичной точки

Очень большие и очень малые числа могут записываться при помощи научной (экспоненциальной) нотации (имеет вид Mep, где M – число, e - означает "умножить на 10 в степени...", p – порядок или степень, в которую возводится 10):

Var y = 123e5; // 12300000 var z = 123e-5; // 0.00123

Логические данные в JavaScript

Есть два логических значения: true (истина) и false (ложь).

Var x = 5; var y = 5; var z = 6; (x == y) // Вернет true (x == z) // Вернет false

Логические значения часто используются в проверках различных условий.

Массивы в JavaScript

Массивы в JavaScript записываются при помощи квадратных скобок.

Элементы массива разделяются запятыми.

В следующем примере декларируется (создается) массив с именем cars, содержащий три элемента:

Var cars = ["Saab", "Volvo", "BMW"];

Индексация элементов массива начинается с нуля. Это означает, что первый элемент имеет индекс , второй и так далее.

Объекты в JavaScript

Объекты в JavaScript записываются при помощи фигурных скобок.

Свойства объектов записываются в виде пар имя:значение , разделенных запятыми.

Var person = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"};

В приведенном выше примере объект с именем person имеет 4 свойства: firstName, lastName, age, eyeColor.

Оператор typeof

Чтобы определить тип данных переменной в JavaScript используется оператор typeof .

Оператор typeof возвращает тип данных переменной или выражения:

Typeof "" // Вернет "string" typeof "John" // Вернет "string" typeof "John Doe" // Вернет "string" typeof 0 // Вернет "number" typeof 314 // Вернет "number" typeof 3.14 // Вернет "number" typeof (3) // Вернет "number" typeof (3 + 4) // Вернет "number"

Тип undefined

В JavaScript переменные без значения на самом деле имеют значение undefined . И оператор typeof также покажет тип undefined .

Var car; // Значение undefined, тип undefined

Любую переменную можно "сбросить", присвоив ей значение undefined . Ее тип также станет undefined .

Car = undefined; // Значение undefined, тип undefined

Пустые значения

Пустое значение не имеет ничего общего со значением undefined .

У пустой строки есть корректные значение и тип.

Var car = ""; // Значение "", тип typeof "string"

Null

В JavaScript значение null означает "ничего". Это что-то чего не существует.

При этом в JavaScript тип null является объектом.

Вы можете обнулить объект присвоив ему значение null :

Var person = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"}; person = null; // Теперь здесь значение null, но тип по прежнему object

Также, обнулить объект можно при помощи значения undefined :

Var person = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"}; person = undefined; // Теперь здесь значение и тип undefined

Разница между undefined и null

Undefined и null равны по значению, но различны по типу:

Typeof undefined // undefined typeof null // object null === undefined // false null == undefined // true

Примитивные данные

Примитивными данными являются одиночные простые значения без дополнительных свойств и методов.

В этом случае оператор typeof возвращает один из следующих примитивных типов:

  • string
  • number
  • boolean
  • undefined
typeof "John" // Вернет "string" typeof 3.14 // Вернет "number" typeof true // Вернет "boolean" typeof false // Вернет "boolean" typeof x // Вернет "undefined" (если у переменной x нет значения)

Сложные (комплексные) данные

В JavaScript существует два сложных или комплексных типа данных:

  • function
  • object

Оператор typeof возвращает тип "object" для объектов, массивов и значения null.

Для функций оператор typeof возвращает тип не "object", а "function".

Typeof {name:"John", age:34} // Вернет "object" typeof // Вернет "object" (не "array", см. ниже) typeof null // Вернет "object" typeof function myFunc(){} // Вернет "function"

Внимание! Для массивов оператор typeof возвращает тип "object", потому что в JavaScript массивы являются объектами.

В этом уроке мы познакомимся с очень важным понятием – типы данных JavaScript. Мы рекомендуем внимательно отнестись к данному понятию – если не осознать его с самого начала, то потом придется часто сталкиваться со странным поведением созданной вами программы.

Динамическая типизация

В процессе работы компьютерные программы манипулируют различными значениями, каждое из которых может быть обработано в языке программирования и относится к определённому типу данных.

В JavaScript типы данных можно разделить на две категории: простые (их также называют примитивными) типы и составные (их также называют ссылочными или объекты).

JavaScript – это слабо типизированный или динамический язык программирования, который позволяет определять типы данных, осуществлять синтаксический анализ и компиляцию как говорится «на лету», на этапе выполнения программы. Это значит, что вам не нужно определять тип переменной заранее. Тип определится автоматически во время выполнения программы.
Таким образом, в различных участках программы одна и та же переменная может принимать значения разных типов:

Типы данных

Стандарт ECMAScript® определяет следующие типы данных:

  • Простые (их также называют примитивными) типы:
    • логический (англ. Boolean) - может принимать два возможных значения, иногда называемых истиной (true) и ложью (false);
    • нулевой (англ. Null) – значение null представляет ссылку, которая указывает, обычно намеренно, на несуществующий или некорректный объект или адрес;
    • неопределённый (англ. Undefined) – обозначает предопределенную глобальную переменную, инициализированную неопределенным значением;
    • числовой (англ. Number) – числовой тип данных в формате 64-битного числа двойной точности с плавающей запятой;
    • строковый (англ. String) – представляет собой последовательность символов, используемых для представления текста;
    • символ (англ. Symbol​) - тип данных, экземпляры которого уникальны и неизменяемы. (новый в ECMAScript 6).
  • Объектный (англ. Object) – это коллекция именованных значений, которые обычно называют свойствами (properties) объекта.

Разница между примитивными и составными типами

Прежде чем рассмотреть каждый тип данных, познакомимся сначала с оператором typeof . Оператор typeof возвращает строку, описывающую тип данных переменной.
Продемонстрируем его работу на следующем примере:

Сценарий в приведенном примере объявляет переменные, выполняет их инициализацию (присваивает значения), а затем выводит тип каждой переменной.

Разница между примитивными и составными типами данных проявляется при копировании их значений.

Когда переменной присваивается значение простого типа, то в переменную записывается само значение (например число). Когда мы присваиваем переменную простого типа в другую, она копирует значение . В результате каждая переменная будет иметь своё значение и изменения в одной из переменных никак не сказывается на значении другой переменной:

Когда переменной присваиваем значение составного (ссылочного) типа, то в переменную записывается ссылка на значение (ссылка на объект ). Когда мы присваиваем одну переменную (в значении которой ссылка на составное значение) другой переменной, то происходит копирование ссылки на составное значение. В результате обе переменные ссылаются на одно и то же составное значение и изменения в значении одной из переменных будут сказываться на другой переменной:

Примитивные типы

Все типы данных в JavaScript, кроме объектов, являются неизменяемыми или иммутабельными (англ. immutable). Это значит, что их значения не могут быть модифицированы, а только перезаписаны новым другим значением. Например, строки нельзя корректировать посимвольно – их можно переписать только полностью. Значения таких типов называются "примитивными".

Простейшие данные, с которыми может оперировать программа, называются литералами. Литералы - это числа или строки, которые используются для представления значений в JavaScript. Предоставляемая информация может быть самой разнообразной, а поэтому значения бывают различных типов. Простейшие типы данных в JavaScript называются основными типами данных: числа, строки и логические значения. Все они относятся к "примитивным".

Булевый (логический) тип «boolean»

Логические, или булевы значения (по фамилии их изобретателя - Буля), могут иметь лишь одно из двух значений: true (истина) или false (ложь). Значения true или false обычно появляются в операциях сравнения или логических операциях.

Приведенная ниже программа создает булеву переменную, а затем тестирует ее значение с использованием инструкции if/else:

В качестве сравнительного выражения можно использовать любое выражение. Любое выражение, которое возвращает значение 0, null, undefined или пустую строку, интерпретируется как false . Выражение, определяющее какое-либо другое значение, интерпретируется как true .

Примечание: При записи булевых значений их не заключают в кавычки: var myVar = true;
В то же время объявление var myVar = "true" создает строковую переменную.

Тип данных Number

В JavaScript, нет различия между целым числом и числом с плавающей точкой – по сути, JavaScript представляет все числа в качестве значения с плавающей точкой.

Для представления чисел в JavaScript используется 64-битный формат, определяемый стандартом IEEE-754 . Этот формат способен представлять числа в диапазоне от ±1,7976931348623157 × 10 308 до ±5 × 10 -324 .

Число, находящееся непосредственно в коде программы, называется числовым литералом. Помимо десятичных целых литералов JavaScript распознает шестнадцатеричные значения.
Числа в шестнадцатиричном формате могут включать любую последовательность цифр от 0 до 9 и буквы от a до f, которая обязательно начинается с последовательности символов «0x».

Var a = 255; var b = 0xFF; // Число 255 в шестнадцатеричной системе исчисления

Кроме того, JavaScript содержит специальные числовые значения:

  • NaN (не число или ошибка вычислений). Является результатом некорректной математической операции над недопустимыми данными, такими как строки или неопределенное значение.
  • Infinity (положительная бесконечность). Используется, если положительное число слишком велико и не может быть представлено в JavaScript.
  • -Infinity (отрицательная бесконечность). Используется, если отрицательное число слишком велико и не может быть представлено в JavaScript.
  • ±0 (положительный и отрицательный 0). JavaScript различает положительный и отрицательный ноль.

Тип данных String

Строковый тип (string) - это неизменяемая, упорядоченная последовательность 16-битных значений, каждое из которых представляет символ Unicode (буквы, цифры, знаки пунктуации, специальные символы и пробелы). Строки могут быть пустыми либо состоять из одного и более символов. Строки создаются при помощи двойных (") или одинарных (") кавычек. В строке, ограниченной парой одинарных кавычек, можно использовать двойные кавычки, и наоборот – одинарные кавычки можно использовать в строке, заключенной в пару двойных кавычек:

В JavaScript нет разницы между двойными и одинарными кавычками, но кавычки в начале и конце строки не должны различаться. Например, такое выражение вызовет синтаксическую ошибку:

var firstName = "Max"; //синтаксическая ошибка - разные кавычки

Примечание: В JavaScript нет специального типа данных для одного символа, такого как char в C, C++ и Java. Одиночный символ представлен строкой единичной длины.

Тип данных Null

Нулевой тип (null) содержит единственное специальное значение – null .

Ключевое слово null невозможно использовать в качестве имени функции или переменной. Значение null является ссылкой на «пустой» объект и имеет специальное назначение – обычно оно используется для инициализации переменной, которой впоследствии будет присвоено значение.

Оператор typeof для значения null возвращает строку «object», что свидетельствует о том, что значение null является специальным «пустым» объектом.

Тип данных Undefined

Неопределенный тип (undefined) образует свой собственный тип, который содержит единственное специальное значение – undefined . Такое значение имеет переменная, объявленная с помощью оператора var , но не инициализированная:

Значение undefined возвращается при обращении к переменной, которой никогда не присваивалось значение, а также к несуществующему свойству объекта или элементу массива.

Следует отметить, что переменная со значением undefined отличается от переменной, которая вообще не определена:

В этом примере метод alert() выводит значение переменной age , то есть undefined . Во втором случае в метод alert() передается необъявленная переменная car , что приводит к ошибке.

Следующй пример может несколько запутать начинающих программистов, т.к. оператор typeof и для неинициализированной, и для необъявленной переменной возвращает значение undefined:

В приведенном примере переменная age объявлена, но в неё ничего не записано, поэтому её значение как раз и есть undefined . Переменная car не объявлена – её, по сути, нет. Тем не менее, typeof возвращает строку undefined в обоих случаях. Некоторый смысл в этом, конечно, есть, потому что с любой из этих переменных невозможно выполнить никаких операций, хотя технически они совершенно разные.

Примечание: Рекомендуется всегда выполнять инициализацию объявленной пременной. В таком случае вы будете знать, что оператор typeof возвращает undefined из-за того, что переменная не была объявлена, а не потому, что она не инициализирована.

Значение undefined является производным от null , так что в ЕСМА-262 оператор эквивалентности == считает их равными:

Несмотря на то, что значения null и undefined связаны, используются они по-разному. Не следует явно присваивать переменной значение undefined , однако к null это требование не относится. В случае, когда необходимый объект недоступен, вместо него следует использовать null . Это указывает на то, что значение null было введено как указатель на пустой объект, и подчеркивает его отличие от undefined .

Чтобы отличать null и undefined в программе можно использовать оператор идентичности === :

Тип данных Символ (Symbol)

Символ (symbol) является нововведением JavaScript начиная с ECMAScript версии 6. Символ – это уникальное, неизменяемое, примитивное значение, которое служит для создания уникальных идентификаторов.

Чтобы создать символ нужно вызвать функцию Symbol:

var mySymbol = Symbol();

Для определения символа можно использовать оператор typeof , в случае если значения является символом будет возвращена строка symbol:

У функции Symbol есть необязательный параметр - строка, которая служит для описания символа:

Важной особенностью символа также является то, что его значение уникально. Вы можете использовать символ как имя свойства, которое гарантированно не будет повторяться с любым другим свойством. Даже, если у двух символов одинаковое имя, то это не значит, что они равны:

Тип данных Object

В дополнение к рассмотренным выше примитивным типам данных JavaScript поддерживает составной тип данных – объект (object). Объект состоит из многих значений (либо элементарных, таких как числа и строки, либо сложных, например других объектов), которые называются свойствами объекта. Доступ к свойствам осуществляется по имени свойства (иногда говорят «по ключу»).

Имя свойства является строкой, поэтому можно считать, что объекты связывают строки со значе­ниями. Вместе эти фрагменты информации образуют пары «ключ-значение».

В JavaScript объекты можно создавать одним из двух синтаксисов:

1. var obj = {}; // с помощью объектного литерала 2. var obj = new Object(); // с помощью метода, называемого конструктором

Создание объекта с помощью объектного литерала начинается с определения обыч­ной переменной. В правой части этой инструкции записывается литерал объекта – это заключенный в фигурные скобки {} список разделенных запятой пар "имя-значение" , заключенный в фигурные скобки. Имя свойства и значение отделены друг от друга двоеточием:

var cat = { "legs": 4, "name": "Мурзик", "color": "Рыжий" }

Второй способ создания объектов связан с использованием конструктора Object() . При этом сначала используется выражение new Object() , а затем определяются и инициализируются свойства полученного объекта:

  • Когда мы присваиваем одну переменную (в значении которой ссылка на составное значение) другой переменной, то происходит копирование ссылки на составное значение. В результате обе переменные ссылаются на одно и то же составное значение и изменения в значении одной из переменных будут сказываться на другой переменной.
  • Любое выражение, которое возвращает значение 0, null, undefined или пустую строку, интерпретируется как false .
  • Строки создаются при помощи двойных (") или одинарных (") кавычек. В строке, ограниченной парой одинарных кавычек, можно использовать двойные кавычки, и наоборот – одинарные кавычки можно использовать в строке, заключенной в пару двойных кавычек.
  • Значение null является ссылкой на «пустой» объект и имеет специальное назначение – обычно оно используется для инициализации переменной, которой впоследствии будет присвоено значение.
  • Значение (undefined) имеет переменная, объявленная с помощью оператора var , но не инициализированная.
  • Решение:

    Важные заметки

    null

    В JavaScript кроме undefined существует null . Оно означает, что «значение отсутствует». Например, если создать переменную, но не задавать ей значения, то у нее будет значение undefined:

    Let a; console.log(a); // undefined

    Тут значения не оказалось ненамеренно. Видимо, просто еще не пришло время дать этой переменной значение.

    null нужен для явного, намеренного указания, что значения нет. Можно сказать let a = null; . Например, вы попросили пользователя ввести информацию, но он ничего не ввел. В таком случае уместно записать в результат null .

    null , в отличие от undefined , можно задавать вручную, передавать как аргумент в функцию и в целом использовать как любое другое явное значение.

    (undefined тоже можно задавать вручную, но никогда не нужно этого делать: это значение семантически создано только для того, чтобы его генерировал компьютер, а не программист).

    При сравнении null и undefined нужно быть осторожным:

    Typeof null; // "object" (не "null" по историческим причинам) typeof undefined; // "undefined" null === undefined; // false null == undefined; // true null === null; // true null == null; // true !null; // true isNaN(1 + null); //false isNaN(1 + undefined); //true

    Сравнение

    В этом курсе мы сравниваем данные, используя три знака равенства:

    A === b; 12 === 12;

    Это сравнение прямое: являются ли эти данные абсолютно идентичными?

    В JavaScript есть расслабленное сравнение, с двумя знаками равенства. Они показывают, что происходит внутри JavaScript, когда он обрабатывает типизации:

    1 === "1"; // false 1 == "1"; // true true === 1; // false true == 1; // true

    Конспект урока

    Типизация в JavaScript

    JavaScript имеет представление о типах: числах, строках, функциях, логических значениях и так далее. typeof возвращает строку, в которой записан тип:

    NaN означает "не число", но тип этого значения - number .

    Переменная без значения имеет специальное значение undefined . Тип такой переменной - undefined:

    Динамическая и статическая типизация

    Код конвертируется в другую форму, которую компьютер может запустить. Этот процесс называется компиляцией, а период времени, за который этот процесс происходит - стадией компиляции (compile time).

    После того, как компиляция закончена, запускается программа и период, пока она запущена, называется стадией исполнения (run time).

    Статически типизированные языки проверяют типы и ищут ошибки типизации на стадии компиляции.

    Динамически типизированные языки проверяют типы и ищут ошибки типизации на стадии исполнения.

    Иными словами: статическое типизирование означает проверку типов перед запуском программы; динамическое - проверку типов пока программа запущена.

    Слабая и сильная типизация

    JavaScript часто конвертирует типы автоматически:

    JavaScript - это язык со слабой типизацией. У него есть представление о типах, но он расслаблено к ним относится и может оперировать значениями, можно сказать, произвольно. Чем сильнее система типизации, тем строже правила.

    Явные конверсии в JavaScript

    Опционально

    Fun

    Транскрипт урока

    В одном из прошлых уроков мы говорили об ошибках и как с ними справляться. Есть несколько видов ошибок, и я хочу напомнить об одном конкретном виде. Вот небольшой фрагмент того урока:

    Взгляните на этот код:

    Const length = 12; const num = length(54);

    Сначала мы создали константу. Помните, что это как давать чему-то название: в нашем случае - числу 12 даётся название length . В следующей строке мы вызываем функцию length и передаём ей аргумент - число 54. Но подождите! length - это не функция! Это всего лишь число. Числа - это не функции, не ящики, которые производят какие-то действия. И JavaScript пожалуется именно на это:

    → node test.js /Users/rakhim/test.js:2 const num = length(-54); ^ TypeError: length is not a function at Object. (/Users/rakhim/test.js:2:13) at Module._compile (module.js:571:32) at Object.Module._extensions..js (module.js:580:10) at Module.load (module.js:488:32) at tryModuleLoad (module.js:447:12) at Function.Module._load (module.js:439:3) at Module.runMain (module.js:605:10) at run (bootstrap_node.js:420:7) at startup (bootstrap_node.js:139:9) at bootstrap_node.js:535:3

    Это Ошибка типизации : тип объекта, который вы использовали, неверный. Интерпретатор JavaScript не скажет чем что-то является , но точно скажет чем оно не является . length - это не функция.

    Ошибка типизации - это как просить кошку постирать бельё. Возможно, вы хотели попросить об этом вашего друга.

    В программировании "типизация" - это классификация информации. Это общий термин и разные языки программирования справляются с типизацией по-разному. Как вы уже знаете, JavaScript умеет отличать типы. Функция - это один тип, Число - другой, и вы не можете просто использовать число как функцию.

    typeof - это специальный оператор, который возвращает строку, в которой написан тип.

    Typeof 42; // "number" typeof 3.14; // "number" typeof NaN; // "number" typeof "Berry"; // "string" typeof true; // "boolean" typeof false; // "boolean"

    42 и 3.14, очевидно, числа, несколько комбинаций букв в кавычках - строка, а true и false - булеан. Всё это - типы в JavaScript - число, строка и булеан.

    NaN означает - "не число", но тип NaN - это "число". Да, я знаю. Еще одна странность JavaScript. Такие правила в этом языке.

    Типизация полезна. Когда мы попытаемся запустить число, как будто это функция, JavaScript начнёт жаловаться и мы увидим ошибку и починим её. Если бы никакого обозначения типов в JavaScript не было, мы бы сталкивались либо с каким-нибудь аномальным поведением, либо с мистической ошибкой. Вместо чёткого "length - это не функция", мы бы видели что-то вроде "I"m sorry Dave, I"m afraid I can"t do that".

    А что, если создать переменную, но не задать ей никакого значения? Какой в этом случае будет тип? Это ни число, ни строка, ничто... Потому что нет значения, правильно?

    JavaScript в этом случае кое-что делает в тайне от вас. Переменная без значения на самом деле имеет специальное значение - "undefined". И тип такой переменной называется "undefined".

    Let a; console.log(a); // undefined typeof a; // "undefined"

    Например, тип number имеет множество потенциальных значений: 1, 2, -10, 69000 и другие числа. А тип undefined только одно - undefined .

    Когда дело касается типизации в программировании, важно различать две концепции: динамическая против статической и слабая против сильной.

    Чтобы понимать разницу между динамической и статической типизацией, нам сначала нужно посмотреть как написанные программы становятся запущенными программами.

    Код, который вы пишите, обычно конвертируется в понятную для запуска компьютером форму. Этот процесс называется компиляцией, а промежуток времени, за который это происходит - "стадией компиляции" или compile time.

    После того, как компиляция закончена и программа запущена, начинается отсчёт времени, который называется "стадией исполнения" или run time.

    Некоторые языки проверяют типы и ищут ошибки типизации на стадии компиляции. У них статическая типизация.

    Другие языки проверяют типы и ищут ошибки типизации на стадии исполнения. Такая типизация - динамическая.

    Иными словами: статическая типизация означает проверку типов перед запуском программы, динамическая - проверку типов, когда программа запущена.

    C#, C++, Java, Go - статически типизированные языки. Если в одном из этих языков вы создадите число и попытаетесь проводить с ним операции, как с функцией, вы получите ошибку во время компиляции, а программа не станет запускаться - она даже не дойдёт до этой стадии, потому что ошибка типизации будет обнаружена перед исполнением, в период компиляции.

    JavaScript, Ruby, PHP - динамически типизированные языки. Как вы видели раньше, если использовать неверную типизацию, ваша программа запустится, а ошибка обнаружится только когда будет исполняться конкретная строчка кода. Здесь типы проверяются в период исполнения.

    Вообще-то, в JavaScript обычно нет никакой компиляции, но это тема другого урока.

    Динамическая типизация не хуже и не лучше статической. Оба способа имеют свои преимущества и недостатки. Динамически типизированные языки обычно проще изучать и писать на них программы, но, как вы можете представить, это потенциально увеличивает ошибки и баги.

    Теперь давайте поговорим о слабой и сильной типизации. Посмотрите на этот JavaScript код:

    4 + "7"; // "47" 4 * "7"; // 28 2 + true; // 3 false - 3; // -3

    М-да… Это… Ок, что тут происходит? Сложение числа 4 со строкой "7" даёт нам строку "47". JavaScript конвертирует число 4 в строку "4" и конкатенирует две строки - склеивает их друг с другом. JavaScript просто берёт на себя ответственность предположить, что это то, что мы хотели. Глупо обвинять его - чего мы действительно хотели? Складывать число со строкой не имеет никакого смысла. Какой-нибудь другой язык, вроде Ruby или Python просто бы пожаловался и ничего не сделал.

    Произведение числа 4 со строкой "7", это, как видите, 28, по мнению JavaScript. В этом случае он сконвертировал строку "7" в число 7 и произвёл обычное умножение.

    JavaScript постоянно так делает. Он знает о типах разных значений, но когда типы не соответствуют, он пытается предположить и сконвертировать один тип в другой, не предупреждая вас. Иногда это полезно, иногда мозгодробяще. Такое происходит потому что JavaScript - язык со слабой типизацией. У него есть представление о типах, но он типа "это всего лишь игра, чего ты злишься?"

    У этой концепции нет ничего общего с динамической и статической типизацией, смысл которых - КОГДА проверять типы. Сильная против слабой - это НАСКОЛЬКО СЕРЬЁЗНО проверять типы.

    В отличие от динамичности-статичности, сила типизации это спектр. У PHP типизация немного сильнее. У Python ещё сильнее. И все они динамически типизированные языки.

    JavaScript делает множество неявных конверсий, но он так же даёт нам инструменты, чтобы мы могли делать явные конверсии сами. Мы можем конвертировать строки в числа, числа в строки, булевы в строки и так далее:

    Number("590"); // 590 Number("aaa!!"); // NaN Boolean(1); // true Boolean(0); // false String(true); // "true" String(false); // "false" String(44843); // "44843"

    Можно предположить, что неявная конверсия из типа в тип - не самая лучшая идея. Неявный, значит скрытый, а скрытый - значит трудно понимаемый и предрасположенный к ошибкам. Поведение программы становится менее очевидным. Вы пишите меньше кода, да, но код более хрупкий и менее понятный.

    Programming languages all have built-in data structures, but these often differ from one language to another. This article attempts to list the built-in data structures available in JavaScript and what properties they have; these can be used to build other data structures. Wherever possible, comparisons with other languages are drawn.

    Dynamic typing

    JavaScript is a loosely typed or a dynamic language. Variables in JavaScript are not directly associated with any particular value type, and any variable can be assigned (and re-assigned) values of all types:

    Var foo = 42; // foo is now a number foo = "bar"; // foo is now a string foo = true; // foo is now a boolean

    Data types

    The latest ECMAScript standard defines eight data types:

    • Seven data types that are :

    Primitive values

    All types except objects define immutable values (values, which are incapable of being changed). For example and unlike to C, Strings are immutable. We refer to values of these types as "primitive values".

    Boolean type

    Boolean represents a logical entity and can have two values: true , and false . See Boolean and Boolean for more details.

    Null type

    Properties

    In JavaScript, objects can be seen as a collection of properties. With the object literal syntax , a limited set of properties are initialized; then properties can be added and removed. Property values can be values of any type, including other objects, which enables building complex data structures. Properties are identified using key values. A key value is either a String or a Symbol value.

    There are two types of object properties which have certain attributes: The data property and the accessor property.

    Data property

    Associates a key with a value and has the following attributes:

    Attributes of a data property
    Attribute Type Description Default value
    [] Any JavaScript type The value retrieved by a get access of the property. undefined
    [] Boolean If false , the property"s [] can"t be changed. false
    [] Boolean for...in loops. See also Enumerability and ownership of properties false
    [] Boolean If false , the property can"t be deleted, can"t be changed to an accessor property and attributes other than [] and [] can"t be changed. false
    Obsolete attributes (as of ECMAScript 3, renamed in ECMAScript 5)
    Attribute Type Description
    Read-only Boolean Reversed state of the ES5 [] attribute.
    DontEnum Boolean Reversed state of the ES5 [] attribute.
    DontDelete Boolean Reversed state of the ES5 [] attribute.

    Accessor property

    Associates a key with one or two accessor functions (get and set) to retrieve or store a value and has the following attributes:

    Attributes of an accessor property
    Attribute Type Description Default value
    [] Function object or undefined The function is called with an empty argument list and retrieves the property value whenever a get access to the value is performed. See also get . undefined
    [] Function object or undefined The function is called with an argument that contains the assigned value and is executed whenever a specified property is attempted to be changed. See also set . undefined
    [] Boolean If true , the property will be enumerated in for...in loops. false
    [] Boolean If false , the property can"t be deleted and can"t be changed to a data property. false

    Note: Attribute is usually used by JavaScript engine, so you can"t directly access it (see more about Object.defineProperty()). That"s why the attribute is put in double square brackets instead of single.

    "Normal" objects, and functions

    A JavaScript object is a mapping between keys and values. Keys are strings (or Symbol s) and values can be anything. This makes objects a natural fit for hashmaps .

    Functions are regular objects with the additional capability of being callable.

    Dates

    When representing dates, the best choice is to use the built-in Date utility in JavaScript.

    Indexed collections: Arrays and typed Arrays

    Arrays are regular objects for which there is a particular relationship between integer-key-ed properties and the "length" property. Additionally, arrays inherit from Array.prototype which provides to them a handful of convenient methods to manipulate arrays. For example, indexOf (searching a value in the array) or push (adding an element to the array), etc. This makes Arrays a perfect candidate to represent lists or sets.

    Typed Arrays are new to JavaScript with ECMAScript 2015 and present an array-like view of an underlying binary data buffer. The following table helps you to find the equivalent C data types:

    TypedArray objects

    Type Value Range Size in bytes Description Web IDL type Equivalent C type
    Int8Array -128 to 127 1 8-bit two"s complement signed integer byte int8_t
    Uint8Array 0 to 255 1 8-bit unsigned integer octet uint8_t
    Uint8ClampedArray 0 to 255 1 8-bit unsigned integer (clamped) octet uint8_t
    Int16Array -32768 to 32767 2 16-bit two"s complement signed integer short int16_t
    Uint16Array 0 to 65535 2 16-bit unsigned integer unsigned short uint16_t
    Int32Array -2147483648 to 2147483647 4 32-bit two"s complement signed integer long int32_t
    Uint32Array 0 to 4294967295 4 32-bit unsigned integer unsigned long uint32_t
    Float32Array 1.2x10 -38 to 3.4x10 38 4 32-bit IEEE floating point number (7 significant digits e.g. 1.1234567) unrestricted float float
    Float64Array 5.0x10 -324 to 1.8x10 308 8 64-bit IEEE floating point number (16 significant digits e.g. 1.123...15) unrestricted double double
    BigInt64Array -2 63 to 2 63 -1 8 64-bit two"s complement signed integer bigint int64_t (signed long long)
    BigUint64Array 0 to 2 64 -1 8 64-bit unsigned integer bigint uint64_t (unsigned long long)

    Keyed collections: Maps, Sets, WeakMaps, WeakSets

    These data structures take object references as keys and are introduced in ECMAScript Edition 6. Set and WeakSet represent a set of objects, while Map and WeakMap associate a value to an object. The difference between Maps and WeakMaps is that in the former, object keys can be enumerated over. This allows garbage collection optimizations in the latter case.

    One could implement Maps and Sets in pure ECMAScript 5. However, since objects cannot be compared (in the sense of "less than" for instance), look-up performance would necessarily be linear. Native implementations of them (including WeakMaps) can have look-up performance that is approximately logarithmic to constant time.

    Usually, to bind data to a DOM node, one could set properties directly on the object or use data-* attributes. This has the downside that the data is available to any script running in the same context. Maps and WeakMaps make it easy to privately bind data to an object.

    Structured data: JSON

    JSON (JavaScript Object Notation) is a lightweight data-interchange format, derived from JavaScript but used by many programming languages. JSON builds universal data structures. See JSON and JSON for more details.

    More objects in the standard library

    JavaScript has a standard library of built-in objects. Please have a look at the reference to find out about more objects.

    Determining types using the typeof operator

    The typeof operator can help you to find the type of your variable. Please read the for more details and edge cases.

    Specifications

    Specification Status Comment
    ECMAScript 1st Edition (ECMA-262) Standard Initial definition.
    ECMAScript 5.1 (ECMA-262)
    The definition of "Types" in that specification.
    Standard
    ECMAScript 2015 (6th Edition, ECMA-262)
    Standard Added Symbol.
    ECMAScript Latest Draft (ECMA-262)
    The definition of "ECMAScript Data Types and Values" in that specification.
    Draft

    В процессе работы компьютерные программы манипулируют значениями, такими как число 7 или текст "HelloWorld!". Каждое значение, которое может быть представлено и обработано в языке программирования относится к определённому типу данных . Тип данных определяет типы значений, которые используются в языке программирования.

    В JavaScript типы данных можно разделить на две категории: простые (их также называют примитивными ) типы и составные (их также называют ссылочными или объекты ).

    • string - текстовые строки (обычно их называют просто - строки)
    • number - числа
    • boolean - логические (булевы) значения

    Так же к простым типам относятся два специальных значения:

    • null
    • undefined

    К составным типам данных относятся:

    • function - функции
    • array - массивы
    • object - объекты

    Разница между простыми и составными типами

    Разница между простыми и составными типами проявляется при копировании значений.

    Когда переменной (параметру функции, свойству или элементу массива) присваивается значение простого типа, например число, то в переменную записывается само значение (в данном случае - число). При выполнении присваивания одной переменной (со значением простого типа) другой переменной происходит копирование значения. В результате каждая переменная имеет свою копию значения и изменения в одной из переменных никак не сказывается на значении другой:

    Var num1 = 10; var num2 = num1; // Копируем значение alert("num1: " + num1 + // 10 "\nnum2: " + num2); // 10 num1 = 15; // Изменяем значение alert("num1: " + num1 + // 15 "\nnum2: " + num2); // 10

    Когда переменной (параметру функции, свойству или элементу массива) присваивается значение составного типа, например объект, то в переменную записывается ссылка на значение (в данном случае - ссылка на объект). При выполнении присваивания одной переменной (в значении которой ссылка на составное значение) другой переменной происходит копирование ссылки на составное значение. В результате обе переменные ссылаются на одно и то же составное значение и любые внесённые изменения в значении одной из переменных будут сказываться на другой переменной:

    Var o1 = {x:10}; var o2 = o1; // Копируем ссылку на объект alert("o1.x: " + o1.x + // 10 "\no2.x: " + o2.x); // 10 o2.x = 15; // Изменяем значение alert("o1.x: " + o1.x + // 15 "\no2.x: " + o2.x); // 15

    null и undefined

    Тип null имеет всего одно значение - null . Значение null является ссылкой на пустой объект и имеет специальное назначение - обычно оно используется для инициализации переменной, которой впоследствии будет присвоен объект.

    Тип undefined имеет всего одно значение - undefined . Значение undefined указывает на изначальное отсутствие какого-либо значения. Получить значение undefined можно следующим образом:

    • При обращении к переменной, которая была объявлена, но не была инициализирована.
    • При обращении к несуществующему свойству объекта.
    • При обращении к несуществующему элементу массива.
    • При обращении к параметрам функции, которые не были инициализированы аргументами при вызове функции.
    • Возвращается функциями, которые не имеют возвращаемого значения.
    • Возвращается оператором typeof, если операндом является несуществующая переменная.
    var bar; document.write(bar); Попробовать »

    Идентификатор undefined является именем предопределённой глобальной переменной, которая инициализирована значением undefined . Переменная undefined доступна только для чтения.

    Объекты обёртки

    Каждый раз, когда в программе предпринимается попытка обратиться к свойству или методу значения примитивного типа, интерпретатор временно преобразует примитивное значение в объект соответствующего типа. Временные объекты, в которые преобразуются значения примитивного типа, называют объектами обёртками . Эти объекты используются интерпретатором для доступа к нужному свойству или методу. Сразу после обращения к свойству или методу объект обёртка уничтожается. Объекты обёртки создаются только для значений типа number , string и boolean . Значения null и undefined не имеют объектов оберток: любые попытки обратиться к свойствам этих значений будут вызывать ошибку.

    Если для объекта обёртки попытаться установить новое свойство то, новое свойство не будет сохранено, так как объект обёртка уничтожается сразу после того, как выполнит свою работу:

    Var str = "текст"; str.len = 5; // Установить свойство со значением. Сразу после этого объект уничтожается alert(str.len); // undefined, так как предыдущий объект обёртка уже уничтожен

    Объекты обёртки можно рассматривать просто как реализацию удобства для работы со значениями примитивного типа и вообще не думать о них.