Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Типы данных JavaScript и структуры данных

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

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

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

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

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

Типы данных

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

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

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

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

Все типы, за исключением объектов, являются неизменными, особенно строки (в отличии от C например). Мы относимся к значениям этих типов как примитивным. Более подробно это объясняется далее, в главе строки.

Булев тип, null и undefined

Эти типы представлены четырьмя константами: true, false, null и undefined. Так как они являются константами, они не могут представлять сложные данные (или структуры данных).

Числа

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

Хотя число часто представляется только по его значению, JavaScript содержит несколько бинарных операций. Они могут использоваться чтобы представлять несколько Boolean значений в одном числе с помощью битовой маски. Это считается плохой практикой, так как  JavaScript предлагает другие способы представления Boolean значений (например, массив элементов с Boolean значениями или объект, содержащий в качестве значений свойств тип Boolean), кроме того битовые маски часто делают код более трудным для чтения, понимания и дальнейшего поддержания. It may be necessary to use such techniques in very constrained environments, like when trying to cope with the storage limitation of local storage or in extreme cases when each bit over the network counts. Данный подход следует использовать в последнюю очередь, когда не остается других вариантов для оптимизации размера вашего кода.

Строки

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

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

Beware of "stringly-typing" your code!

It can be tempting to use strings to represent complex data. They have a couple of nice properties:

  • It's easy to build complex strings with concatenation.
  • Strings are easy to debug (what you see printed is always what is in the string).
  • Strings are the common denominator of a lot of APIs (input fields, local storage values, XMLHttpRequest responses when using responseText, etc.) and it can be tempting to only work with strings.

With conventions, it is possible to represent any data structure in a string. This does not make it a good idea. For instance, with a separator, one could emulate a list (while a JavaScript array would be more suitable). Unfortunately, when the separator is used in one of the "list" elements, then, the list is broken. An escape character can be chosen, etc. All of this requires conventions and becomes a maintenance burden which does not exist when the right tool for the right job is used.

It is recommended to use strings for textual data and symbolic data, but to parse strings and use the right abstraction for what it is supposed to represent otherwise.

Объекты

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

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

Объект JavaScript это набор ключей и значений. Ключи являются строковым типом, а значения могут быть любого типа. This makes objects a natural fit for hashmaps. However, one has to be careful about the non-standard __proto__ pseudo property. In environment that supports it, '__proto__' does not allow to manipulate one property with such a name, but the object prototype. In context where it is not necessarily known where the string comes from (like an input field), caution is required: other have been burned by this. In that case, an alternative is to use a proper StringMap abstraction.

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

Массивы

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 like 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.

Даты

When considering representing dates, the best choice is certainly to use the built-in Date utility

WeakMaps, Maps, Sets

Non-standard. Likely to be standardized as part of ECMAScript 6.

These data structures take object references as keys. A Set represents a set of objects, while WeakMaps and Maps associates 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 easy to privately bind data to an object.

Типизированные массивы

Не стандартизированы. Планируется сделать частью стандарта ECMAScript 6.

See also

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

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