Javascript.RU

Типы

Update: Более новый материал по этой теме находится по адресу http://es5.javascript.ru.
8. Типы

Значение - это сущность, которая может иметь один из девяти типов. Всего определено девять различных типов (Undefined, Null, Boolean, String, Number, Object, Reference, List и Completion). Значения типов Reference, List и Completion используются только как промежуточные результаты вычисления выражений и не могут быть сохранены как свойства объектов.

8.1 Тип Undefined

Для типа Undefined ("не определено") существует единственное значение - undefined. Значением любой переменной, которой ещё не было присвоено значения, является undefined.

8.2 Тип Null

Для типа Null ("пусто", "ничто") существует единственное значение - null.

8.3 Тип Boolean

Тип Boolean ("булевский", "логический") представляет собой логическую сущность, которая может принимать одно из двух значений: true или false.

8.4 Тип String

Тип String ("строка") представляет собой множество всех конечных упорядоченных последовательностей из нуля или более 16-разрядных беззнаковых целых значений ("элементов"). Тип String обычно используется для представления текстовых данных в исполняемой программе на ECMAScript. В этом случае каждый элемент строки трактуется как значение кода Юникода (см. раздел 6). Каждый элемент считается занимающим определённую позицию в последовательности. Эти позиции пронумерованы неотрицательными целыми числами. Первый элемент (если присутствует) находится на позиции 0, следующий элемент (если присутствует) на позиции 1, и т.п. Длина строки равна количеству элементов (т. е. 16-битных значений), из которых она состоит. Пустая строка имеет длину ноль, и, таким образом, не содержит элементов.

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

Замечание
Основанием для подобных решений было стремление сделать реализации типа String как можно более простыми и высокопроизводительными. Подразумевается, что текстовые данные, поступающие в среду выполнения извне (например пользовательский ввод, читаемый из файла или получаемый по сети текст и т.п.) должны быть преобразованы в нормализованную форму C Юникода ещё до того, как их увидит исполняющаяся программа. Предполагается, что это должно происходить одновременно с преобразованием текста из исходной кодировки в Юникод (и, таким образом, не вносит дополнительных затрат по времени или сложности). Поскольку рекомендуется, чтобы исходный код программы на ECMAScript был в нормализованной форме C, гарантируется нормализованность строковых литералов (при условии нормализации исходного кода), если они не содержат юникодных escape-последовательностей
.

8.5 Тип Number

У типа Number ("число") имеется ровно 18 437 736 874 454 810 627 (т.е., 264-253 +3) различных значений, представляющих 64-разрядные значения двойной точности формата IEEE 754 согласно Стандарту IEEE на двоичную арифметику с плавающей запятой, за исключением того, что 9007199254740990 (т.е., 253-2) различных значений "не-число" Стандарта IEEE представлены в ECMAScript как единственное специальное значение NaN. (Заметим, что значение NaN получается в программе при помощи выражения NaN, если глобальная переменная NaN не была изменена в ходе выполнения программы.) В некоторых реализациях для внешнего кода различные значения "не-число" могут быть различимыми, но такое поведение зависит от конкретной реализации. Для кода на ECMAScript все значения NaN являются неотличимыми друг от друга.

Существуют два других особых значения, называемые положительная бесконечность и отрицательная бесконечность. Для краткости и в пояснительных целях эти значения также могут обозначаться +∞ и -∞ соответственно. (Заметим, что эти два значения получаются в программе при помощи выражений +Infinity (или просто Infinity) и -Infinity, если глобальная переменная Infinity не была изменена в ходе выполнения программы.)

Прочие 18 437 736 874 454 810 624 (т.е. 264-253) значений называются конечными числами. Половина из этих значений является положительными числами, а половина - отрицательными. Для каждого конечного положительного числа имеется соответствующее отрицательное число, равное ему по модулю.

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

18 437 736 874 454 810 622 (т.е., 264-253-2) конечных ненулевых значений разделяются на два типа:

18 428 729 675 200 069 632 (т.е., 264-254) из них нормализованы и имеют вид

s * m * 2e

где s равно +1 или -1, m - положительное целое меньше, чем 253, но не меньше чем 252 и e - целое в диапазоне от -1074 до 971 включительно.

Оставшиеся 9 007 199 254 740 990 (т.е. 253-2) значений денормализованы и имеют вид:

s * m * 2e

где s равно +1 or -1, m - положительное целое, меньше чем 252 и e равно -1074.

Заметим, что все положительные и отрицательные целые, модуль которых не превышает 253, представимы типом Number (причём у 0 есть два представления: +0 и -0).

Конечное число является нечётно значимым, если оно не равно нулю и целое m, использованное для его представления (в одном из приведённых выше видов) - нечётное. Иначе оно является чётно значимым.

В данной спецификации фраза "численное значение x", где x обозначает точное ненулевое вещественное математическое значение (которое может даже являться иррациональным числом, таким как π), означает численное значение, выбранное по следующему принципу. Представим множество всех конечных значений типа Number, из которого удалён -0 и добавлены два дополнительных значения, не представимых в типе Number: 21024 (т.е. +1 * 253 * 2971) и -21024 (т.е. -1 * 253 * 2971 ). Выберем из этого множества элемент, наиболее близкий по значению к x. Если два значения в множестве являются одинаково близкими, из них выбирается чётно значимое, причём для этих целей два дополнительных значения 21024 и -21024 считаются чётно значимыми. Наконец, если было выбрано 21024, заменяем его на +∞; если было выбрано -21024, заменяем его на -∞; если было выбрано +0, заменяем его на -0 в том и только в том случае, когда x меньше нуля; любое другое значение оставляем без изменений. Результат является численным значением для x. (Эта процедура в точности соответствует режиму "округление к ближайшему" стандарта IEEE 754.)

Некоторые операторы ECMAScript работают только с целыми значениями из диапазона от -231 до 231-1 включительно или из диапазона от 0 до 232-1 включительно. Эти операторы принимают любое значение типа Number, но предварительно преобразовывают каждое из таких значений к одному из 232 целочисленных значений. См. описания операторов ToInt32 и ToUint32 в разделах 0 и 0 соответственно.

8.6 Тип Object

Object ("объект") представляет собой неупорядоченный набор свойств. Каждое свойство состоит из имени, значения и набора атрибутов.

8.6.1 Атрибуты свойства

Свойство может обладать нулём или более атрибутов из следующего множества:

Атрибут Описание
ReadOnly Это свойство является свойством только для чтения. Попытки записать в это свойство в коде ECMAScript будут проигнорированы. (Однако заметим, что в некоторых случаях значение свойства с атрибутом ReadOnly может со временем изменяться в зависимости от действий, производимых средой выполнения. Таким образом "только для чтения" не означает "постоянное и неизменное"!)
DontEnum Свойство не должно перечисляться в ходе цикла for-in (раздел 12.6.4).
DontDelete Попытки удалить свойство будут проигнорированы. См. описание оператора delete в разделе 11.4.1.
Internal Внутреннее свойство - не имеет имени и не доступно напрямую через операторы доступа к свойствам. Доступ к этим свойствам зависит от конкретной реализации. Случаи использования некоторых из этих свойств описываются в спецификации языка.
8.6.2 Внутренние свойства и методы

Внутренние свойства и методы не являются частью языка. Они определены данной спецификацией исключительно для разъяснительных целей. Реализация ECMAScript должна вести себя, как будто она создаёт и использует внутренние свойства согласно приведённому здесь описанию. В данном документе имена внутренних свойств будут заключаться в двойные прямоугольные скобки [[ ]]. Когда алгоритм использует внутреннее свойство, которое не реализовано в данном объекте, бросается исключение TypeError.

Существуют два типа доступа к обычным (не внутренним) свойствам: get и put, отвечающие соответственно за чтение и присваивание.

Встроенные объекты ECMAScript обладают внутренним свойством [[Prototype]]. Значением этого свойства является либо null, либо объект. Это значение используется для реализации наследования. Свойства объекта [[Prototype]] видятся как свойства дочернего объекта с точки зрения доступа get, но не с точки зрения доступа put.

В следующей таблице приведена сводная информация по внутренним свойствам, определённым в данной спецификации. Здесь описывается их поведение для встроенных объектов ECMAScript. В объектах среды реализации этих внутренних методов могут обладать любым специфическим для реализации поведением. Также возможно, что в объекте среды будут реализованы не все из внутренних методов, а только некоторые.

Свойство Параметры Описание
[[Prototype]] нет Прототип данного объекта.
[[Class]] нет Строковое значение, обозначающее тип данного объекта.
[[Value]] нет Внутренняя информация о состоянии, связанная с данным объектом.
[[Get]] (ИмяСвойства) Возвращает значение свойства.
[[Put]] (ИмяСвойства, Значение) Записывает Значение в указанное свойство.
[[CanPut]] (ИмяСвойства) Возвращает булевское значение, описывающее, можно ли успешно использовать операцию [[Put]] с данным ИменемСвойства.
[[HasProperty]] (ИмяСвойства) Возвращает булевское значение, описывающее, существует ли уже у объекта свойство с данным именем.
[[Delete]] (ИмяСвойства) Удаляет указанное свойство из объекта.
[[DefaultValue]] (Подсказка) Возвращает для объекта значение по умолчанию, которое должно являться элементарным значением (не объект или ссылка).
[[Construct]] список аргументов переданный вызывающим Создаёт объект. Вызывается при помощи оператора new. Объекты, в которых реализован этот внутренний метод, называются конструкторами.
[[Call]] список аргументов переданный вызывающим Выполняет код, связанный с данным объектом. Вызывается при помощи выражения вызова функции. Объекты, в которых реализован этот внутренний метод, называются функциями.
[[HasInstance]] (Свойство) Возвращает булевское значение, описывающее, делегирует ли Value своё поведение данному объекту. Из всех встроенных объектов ECMAScript только в Function реализован метод [[HasInstance]].
[[Scope]] нет Иерархия областей видимости, определяющая среду, в которой исполняется объект Function.
[[Match]] (Строка, Индекс) Проверяет соответствие регулярному выражению и возвращает значение MatchResult (см. раздел 15.10.2.1).

В каждом объекте (включая объекты среды) должны быть реализованы свойства [[Prototype]] и [[Class]] и методы [[Get]], [[Put]], [[CanPut]], [[HasProperty]], [[Delete]] и [[DefaultValue]]. (Однако заметим, что для некоторых объектов метод [[DefaultValue]] может просто бросать исключение TypeError.)

Значением свойства [[Prototype]] ("прототип") может быть либо объект, либо null, и каждая цепь [[Prototype]] должна иметь конечную длину (т.е. если начать с любого объекта, рекурсивный переход на его свойство [[Prototype]] должен в конечном итоге привести к значению null). Наличие возможности использования объекта среды в качестве значения свойства [[Prototype]] для встроенного объекта определяется конкретной реализацией.

Значение свойства [[Class]] определено данной спецификацией для всех типов встроенных объектов. Для объекта среды значение свойства [[Class]] может быть любым и даже совпадать со значением свойства [[Class]] для встроенного объекта. Значение свойства [[Class]] используется реализацией языка для различения разных типов встроенных объектов. Заметим, что данная спецификация не обеспечивает никаких способов доступа к этому значению в программе, за исключением Object.prototype.toString (см. 15.2.4.2).

Для встроенных объектов методы [[Get]], [[Put]], [[CanPut]], [[HasProperty]], [[Delete]] и [[DefaultValue]] ведут себя согласно описанию в разделах 8.6.2.1, 8.6.2.2, 8.6.2.3, 8.6.2.4, 8.6.2.5 и 8.6.2.6 соответственно, за исключением того, что объекты Array реализуют метод [[Put]] несколько иначе (см. раздел 15.4.5.1). Объекты среды могут реализовывать эти методы произвольным путём, если обратное не указывается явно. Например, существует возможность, что методы [[Get]] и [[Put]] для некоторого объекта действительно читают и записывают значения в различные свойства, но при этом [[HasProperty]] всегда возвращает false.

В нижеприведённых описаниях алгоритмов предполагается, что O - это встроенный объект ECMAScript, а P - строка.

8.6.2.1 [[Get]](P)

Когда метод [[Get]] объекта O вызывается с именем свойства P, предпринимаются следующие шаги:

1. Если у O нет свойства с именем P - переход на шаг 4.

2. Получить значение свойства.

3. Вернуть Результат(2).

4. Если свойство [[Prototype]] объекта O равно null - вернуть undefined.

5. Вызвать метод [[Get]] у значения свойства [[Prototype]], передав имя свойства P.

6. Вернуть Результат(5).

8.6.2.2 [[Put]](P, V)

Когда метод [[Put]] объекта O вызывается с именем свойства P и значением V, предпринимаются следующие шаги:

1. Вызвать метод [[CanPut]] у объекта O, передав имя P.

2. Если Результат(1) равен false - возврат.

3. Если у O нет свойства с именем P - переход на шаг 6.

4. Установить значение свойства равным V. Атрибуты свойства при этом не изменяются.

5. Возврат.

6. Создать свойство с именем P, установить его значение в V и дать ему пустые атрибуты.

7. Возврат.

Заметим, однако, что если O - объект типа Array, его метод [[Put]] работает несколько сложнее (15.4.5.1).

8.6.2.3 [[CanPut]](P)

Метод [[CanPut]] используется только методом [[Put]].

Когда метод [[CanPut]] объекта O вызывается для свойства P, предпринимаются следующие шаги:

1. Если у O нет свойства с именем P - переход на шаг 4.

2. Если у свойства есть атрибут ReadOnly - вернуть false.

3. Вернуть true.

4. Если значение свойства [[Prototype]] объекта O равно null - вернуть true.

5. Вызвать метод [[CanPut]] для значения [[Prototype]] объекта O, передав имя свойства P.

6. Вернуть Результат(5).

8.6.2.4 [[HasProperty]](P)

Когда метод [[HasProperty]] объекта O вызывается с именем свойства P, предпринимаются следующие шаги:

1. Если у O есть свойство с именем P - вернуть true.

2. Если значение свойства [[Prototype]] объекта O равно null - вернуть false.

3. Вызвать метод [[HasProperty]] у значения свойства [[Prototype]], передав имя свойства P.

4. Вернуть Результат(3).

8.6.2.5 [[Delete]](P)

Когда метод [[Delete]] объекта O вызывается с именем свойства P, предпринимаются следующие шаги:

1. Если у O нет свойства с именем P - вернуть true.

2. Если у свойства есть атрибут DontDelete - вернуть false.

3. Удалить свойство с именем P из объекта O.

4. Вернуть true.

8.6.2.6 [[DefaultValue]](подсказка)

Когда метод [[DefaultValue]] объекта O вызывается с подсказкой типа String, предпринимаются следующие шаги:

1. Вызвать метод [[Get]] у объекта O, передав в качестве аргумента "toString".

2. Если Результат(1) не является объектом - переход на шаг 5.

3. Вызвать метод [[Call]] у Результата(1), передав ему O в качестве значения this и пустой список аргументов.

4. Если Результат(3) является элементарным значением - вернуть Результат(3).

5. Вызвать метод [[Get]] объекта O, передав в качестве аргумента "valueOf".

6. Если Результат(5) не является объектом - переход на шаг 9.

7. Вызвать метод [[Call]] у Результата(5), передав ему O в качестве значения this и пустой список аргументов.

8. Если Результат(7) является элементарным значением - вернуть Результат(7).

9. Бросить исключение TypeError.

Когда метод [[DefaultValue]] объекта O вызывается с подсказкой типа Number, предпринимаются следующие шаги:

1. Вызвать метод [[Get]] объекта O, передав в качестве аргумента "valueOf".

2. Если Результат(1) не является объектом - переход на шаг 5.

3. Вызвать метод [[Call]] у Результата(1), передав ему O в качестве значения this и пустой список аргументов.

4. Если Результат(3) является элементарным значением - вернуть Результат(3).

5. Вызвать метод [[Get]] у объекта O, передав в качестве аргумента "toString".

6. Если Результат(5) не является объектом - переход на шаг 9.

7. Вызвать метод [[Call]] у Результата(5), передав ему O в качестве значения this и пустой список аргументов.

8. Если Результат(7) является элементарным значением - вернуть Результат(7).

9. Бросить исключение TypeError.

Когда метод [[DefaultValue]] объекта O вызывается без указания подсказки, он ведёт себя, как будто в качестве подсказки было указано Number, за исключением случая, когда O - объект типа Date (см. 15.9), в котором он ведёт себя, как будто в качестве подсказки было указано String.

Вышеприведённая спецификация метода [[DefaultValue]] для встроенных объектов может возвращать только элементарные методы. Если объект среды реализует свой собственный метод [[DefaultValue]], он должен обеспечить, чтобы его метод [[DefaultValue]] возвращал только элементарные значения.

8.7 Тип Reference

Внутрений тип Reference ("ссылка") не является языковым типом данных. Он определен данной спецификацией исключительно для разъяснительных целей. Реализация ECMAScript должна вести себя, как будто она создаёт и использует ссылки согласно приведённому здесь описанию. Однако значение типа Reference используется только как промежуточный результат вычисления выражения и не может быть сохранено как переменная или свойство.

Тип Reference используется для объяснения поведения таких операторов как delete, typeof и операторы присваивания. Например в качестве левостороннего операнда операции присваивания ожидается ссылка. В качестве альтернативы, поведение присваивания могло бы быть объяснено анализом конкретной синтаксической формы левостороннего операнда операции присваивания, но с одним осложнением: вызовы функций могут возвращать ссылки. Такая возможность включена исключительно ради объектов среды. Ни одна встроенная функция ECMAScript, определённая в данной спецификации, не возвращает ссылки, и не существует возможности вернуть ссылку из пользовательской функции. (Ещё одним доводом против неиспользования синтаксического анализа является то, что подобный подход был бы длинным и неудобным, затрагивая при этом многие части спецификации.)

Другим применением для типа Reference является объяснение определения значения this в вызове функции.

Значение Reference является ссылкой на свойство объекта. Значение Reference состоит из двух компонент, базового объекта и имени свойства.

Следующие абстрактные операции используются в данной спецификации для доступа к компонентам ссылок:

  • ПолучитьБазу(V). Получает компоненту базового объекта для ссылки V.
  • ПолучитьИмяСвойства(V). Возвращает компоненту имени свойства для ссылки V.

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

8.7.1 ПолучитьЗначение(V)

1. Если Тип(V) не Reference - вернуть V.

2. Вызвать ПолучитьБазу(V).

3. Если Результат(2) равен null - бросить исключение ReferenceError.

4. Вызвать метод [[Get]] объекта Результат(2), передавая ПолучитьИмяСвойства( V) в качестве имени свойства.

5. Вернуть Результат(4).

8.7.2 ЗаписатьЗначение(V, W)

1. Если Тип(V) не Reference - бросить исключение ReferenceError.

2. Вызвать ПолучитьБазу(V).

3. Если Результат(2) равен null - переход на шаг 6.

4. Вызвать метод [[Put]] объекта Результат(2), передавая ПолучитьИмяСвойства( V) в качестве имени свойства и W в качестве значения.

5. Возврат.

6. Вызвать метод [[Put]] для глобального объекта, передавая ПолучитьИмяСвойства( V) в качестве имени свойства и W в качестве значения.

7. Возврат.

8.8 Тип List

Внутрений тип List ("список") не является языковым типом данных. Он определен данной спецификацией исключительно для разъяснительных целей. Реализация ECMAScript должна вести себя, как будто она создаёт и использует значения типа List согласно приведённому здесь описанию. Однако значение типа List используется только как промежуточный результат вычисления выражения и не может быть сохранено как переменная или свойство.

Тип List используется для объяснения поведения списков аргументов (см. 11.2.4), используемых в выражениях new и вызовах функций. Значения типа List представляют из себя простые упорядоченные последовательности значений. Эти последовательности могут иметь любую длину.

8.9 Тип Completion

Внутрений тип Completion ("завершение") не является языковым типом данных. Он определен данной спецификацией исключительно для разъяснительных целей. Реализация ECMAScript должна вести себя, как будто она создаёт и использует значения типа Completion согласно приведённому здесь описанию. Однако значение типа Completion используется только как промежуточный результат вычисления выражения и не может быть сохранено как переменная или свойство.

Тип Completion используется для объяснения поведения инструкций (break, continue, return и throw) которые производят передачу управления наружу из локальной области кода. Значения типа Completion представляют из себя триплеты вида (тип, значение, цель), где тип - один из normal, break, continue, return или throw, значение - любое значение ECMAScript или пусто, а цель - любой идентификатор ECMAScript или пусто.

Термин "предварительное завершение" означает любое завершение с типом, отличным от normal.


Автор: Гость (не зарегистрирован), дата: 25 ноября, 2008 - 13:51
#permalink

Всего определено девять различных типов (Undefined, Null, Boolean, String, Number, Object, Reference, List и Completion)

Но далее по тексту идут упоминания о типе Array - нестыковка.


Автор: Александр Михалицын, дата: 31 октября, 2009 - 07:58
#permalink

Array -- не тип данных языка. У объектов Array тип Object. (-;


Автор: Lyoha (не зарегистрирован), дата: 12 января, 2009 - 12:49
#permalink

"бросается исключение TypeError"

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


Автор: Minh, дата: 21 мая, 2009 - 20:16
#permalink

По мне, бросается очень удачно подходит по смыслу


Автор: Гость (не зарегистрирован), дата: 31 октября, 2009 - 12:32
#permalink

"method throws an Exception".
Так почему же их не бросают?


Автор: Илья Кантор, дата: 31 октября, 2009 - 13:23
#permalink

С одной стороны, слово "бросать" - прямая калька с английского. На русском языке действительно более корректно говорить "генерирует", "инициирует".
С другой стороны, вариант "бросить исключение" тоже применяется, хотя и редко.
Кроме того, в защиту термина "бросить" говорит удобный вариант "пробросить" (для rethrow).
Само слово "исключение" - вообще прямая калька с английского, так почему бы его и не "бросать"?


Автор: BlueIce, дата: 8 января, 2010 - 13:48
#permalink

Вышеприведённая спецификация метода [[DefaultValue]] для встроенных объектов может возвращать только элементарные методы.

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


Автор: Joni (не зарегистрирован), дата: 21 июня, 2014 - 00:00
#permalink

function разве не тип?


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
1 + 2 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Реклама
Содержание

Учебник javascript

Основные элементы языка

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

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum