MDN wants to learn about developers like you: https://qsurvey.mozilla.com/s3/MDN-dev-survey

Перевод не завершен. Пожалуйста, помогите перевести эту статью с английского.

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

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

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

var foo = 42;    // сейчас foo типа Number
var foo = "bar"; // а теперь foo типа String
var foo = true;  // foo становится типа Boolean

Типы данных

Стандарт ECMAScript определяет 7 типов данных:

  • 6 типов данных являются примитивами:
  • и Object (Объект)

Примитивные значения

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

Булевый тип данных

Булевый тип представляет результат логического выражения и принимает одно из двух значений: true (истина) или false (ложь).

Null

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

Undefined

Переменная, значение которой не было присвоено, имеет значение undefined. Смотрите undefined и undefined для получения подробностей.

Числа

В соответствии со стандартом ECMAScript, существует только один числовой тип, который представляет собой "64 битное число двойной точности согласно стандарту IEEE 754". Другими словами, специального типа для целых чисел в JavaScript нет. Обратите на это внимание - это важно. Это означает что при числовых операциях вы можете получить неточное (округленное) значение. Вдобавок к возможности представлять числа с плавающей запятой, есть несколько символических значений: +Infinity (положительная бесконечность), -Infinity (отрицательная бесконечность), и NaN (не число).

Для получения самого большого или самого меньшего доступного значения в пределах +/-Infinity, можно использовать константы Number.MAX_VALUE или Number.MIN_VALUE. А с введением ECMAScript 6, вы также можете проверить, находится ли число в безопасном для целых чисел диапазоне, используя метод Number.isSafeInteger(), либо константы Number.MAX_SAFE_INTEGER и Number.MIN_SAFE_INTEGER. За пределами этого диапазона, операции с целыми числами будут небезопасными, и возвращать приближенные значения.

Ноль в JavaScript имеет два представления -0 and +0. ("0" это синоним +0). На практике это имеет мало заметный эффект. Например, выражение +0 === -0 является истинным. Однако, это может проявиться при делении на ноль:

> 42 / +0
Infinity
> 42 / -0
-Infinity

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

Текстовые строки

В JavaScript, для представления текстовых данных служит тип  String. Он представляет собой цепочку "элементов" 16-битных беззнаковых целочисленных значений. Каждый такой элемент занимает свою позицию в строке. Первый элемент имеет индекс 0, следующий - 1, и так далее. Длинна строки - это количество элементов в ней.

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

  • Получить часть исходной строки выборкой отдельных символов, либо применением метода String.substr().
  • Объекдинить две строки в одну применив оператор (+) или метод String.concat().

Избегайте повсеместного использования строк в своем коде!

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

  • Легко соединять данные в кучу сложением строк.
  • Легко отлаживать (данные выглядят как есть в читаемом текстовом виде).
  • Строки, это распространенный формат данных, используемый разнообразными АПИ (поля ввода, значения локальнго хранилища, XMLHttpRequest возвращает ответ в виде строки, и т. д.) и это очень большой соблазн использовать только строки.

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

Используйте строки только для текстовых данных. Для составных структур преобразуйте строки в подобающие конструкции.

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

Символы являются нововведением JavaScript начиная с ECMAScript версии 6. Символ - это уникальное, иммутабелное, примитивное значение, которое может быть использовано как ключ для свойства объекта (смотрите ниже). В некоторых языках программирования, символы называются атомами. Их также можно сравнить с именованными значениями перечисления (enum) в языке C. Подробнее смотрите Symbol и Symbol.

Объекты

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

Свойства

В JavaScript, объект может расцениваться как набор свойств. Литеральная инициализация объекта задает определенное количество начальных свойств, и в процессе работы приложения поля могут добавляться и удаляться. Значения свойств могут иметь любой тип, включая другие объекты, что позволяет строить сложные, разветвленные иерархии данных. Каждое свойство объекта идентифицируется ключом, в качестве которого может выступать значение с типом Строка или Символ.

Есть два типа свойств: свойство-значение и свойство-акцессор (свойство обернутое в геттер и сеттер). Они отличаются определенными атрибутами.

Свойство-значение

Ассоциирует ключ со значением, и имеет следующие атрибуты:

Атрибуты свойства-значения
Атрибут Тип Описание Значение по умолчанию
[[Value]] Любой тип JavaScript Значение, возвращаемое при обращении к свойству. undefined
[[Writable]] Boolean Если false, то [[Value]] свойства не может быть изменено. false
[[Enumerable]] Boolean Если true, свойство будет перечислено в цикле for...in. Смотрите подробнее  Перечисляемость и владение свойствами. false
[[Configurable]] Boolean Если false, то свойство не может быть удалено, а его атрибуты, кроме [[Value]] и [[Writable]] не могут быть изменены. false
Устаревшие атрибуты (присутствуют в ECMAScript 3, но переименованы в ECMAScript 5)
Атрибут Тип Описание
Read-only Boolean Зарезервировано по атрибут [[Writable]] ES5.
DontEnum Boolean Зарезервировано по атрибут [[Enumerable]] ES5.
DontDelete Boolean Зарезервировано по атрибут [[Configurable]] ES5.

Свойство-акцессор

Ассоциирует ключ с одной из двух функций-акцессоров (геттер и сеттер) для получения или изменения значения свойства, и имеет следующий атрибуты:

Атрибуты свойства-акцессора
Атрибут Тип Описание Значение по умолчанию
[[Get]] Function или undefined Функция вызывается без параметров, и возвращает значение свойтсва, каждый раз, когда происходит чтение свойтсва. Смотрите также get. undefined
[[Set]] Function или undefined Функция вызывается с одним аргументом, содержащим присваиваемое значение, каждый раз, когда происходит попытка присвойсть свойтсву новое значение. Смотрите также set. undefined
[[Enumerable]] Boolean Если true, свойство будет перечислено в цикле for...in. false
[[Configurable]] Boolean Если false, то свойство не может быть удалено, и не может быть преобразовано в свойство-значение. false

Примечание: Атрибуты обычно используются движком JavaScript, поэтому вы не можете обратиться к ним на прямую (смотрите подробнее Object.defineProperty()). Вот почему в таблицах выше они помещены в двойные квадратные скобки вместо одиночных.

"Обычные" объекты и функции

Объект JavaScript это таблица соотношений между ключами и значениями. Ключи - это строки (или Symbol'ы) а значения могут быть любыми. Это делает объекты полностью отвечающими определению хеш-таблицы.

Функции - это обычные объекты, имеющие дополнительную возможность быть вызванными для исполнения.

Даты

Для работы с датами, служит встроенный глобальный объект Date.

Массивы общие, и типизованные

Массив, это обычный объект, с дополнительной связью между целочисленными ключами его свойств и специальным свойством 'length'. В добавок ко всему, массивы наследуют Array.prototype предоставляющий исчерпывающий набор методов для манипуляции массивами. Например, метод indexOf (служит для поиска значения в массиве) или push (добавляет элемент в конец массива), и т. д.. Все это делает массив идеальным кандидатом на представление списков и перечислений.

Типизованный массив является новинкой ECMAScript Edition 6 и является массиво-подобным представлением для лежащего в его основе бинарного буфера памяти. Следующая таблица поможет вам найти соответствующие типы языка C:

Коллекции: Maps, Sets, WeakMaps, WeakSets

Эти наборы данных используют ссылку на объект в качестве ключа, и введены в JavaScript с приходом ECMAScript Edition 6. Set и WeakSet являют собой набор уникальных объектов, в то время как Map и WeakMap ассоциируют с объектом (выступающим в качестве ключа) некоторое значение. Разница между Map и WeakMap заключается в том, что только у Map ключи являются перечисляемыми. Это позволяет оптимизировать сборку мусора для WeakMap.

Можно было бы написать собственную реализацию Map и Set на чистом ECMAScript 5. Однако, так как объекты нельзя сравнивать на больше или меньше, то производительность поиска в самодельной реализации будет вынужденно линейной. Нативная реализация (включая WeakMap) имеет производительность логарифмически близкую к константе.

Обычно, для привязки некоторых данных к узлу DOM, приходится устанавливать свойства этому узлу непосредственно, либо использовать его атрибуты data-*. Обратной стороной такого подхода является то, что эти данные будут доступны любому скрипту, работающему в том же контексте. Maps и WeakMaps дают возможность приватной привязки данных к объекту.

Структурированные данные: JSON

JSON (JavaScript Object Notation) это легковесный формат обмена данными, происходящий от JavaScript но используемый во множестве языков программирования. JSON строит универсальные структуры данных. Смотрите JSON и JSON для детального изучения.

Больше объектов и стандартная библиотека

JavaScript имеет стандартную библиотеку встроенных объектов. Пожалуйста обратитесь к справочнику чтобы найти описание всех объектов доступных для работы.

Определение типов оператором typeof

Оператор typeof может помочь определить тип вашей переменной. Смотрите страницу документации, где приведены его детали и случаи использования.

Спецификации

Спецификация Статус Коментарий
ECMAScript 1st Edition (ECMA-262) Стандарт Начальное определение.
ECMAScript 5.1 (ECMA-262)
Определение 'Типы' в этой спецификации.
Стандарт  
ECMAScript 2015 (6th Edition, ECMA-262)
Определение 'Типы данных и значения ECMAScript' в этой спецификации.
Стандарт  
ECMAScript Latest Draft (ECMA-262)
Определение 'Типы данных и значения ECMAScript' в этой спецификации.
Живой стандарт  

Смотрите также

Метки документа и участники

 Внесли вклад в эту страницу: rockad, foobar42, letry, Megabyteceer, kmetto, TaKo13, alfaslash, markgraydev, Leo240, KANBY, fscholz, jaguardev, teoli, dunmaksim, uleming
 Обновлялась последний раз: rockad,