Спецификация ECMAScript 5.1 с аннотациями

Поделиться

9 Преобразование и проверка типов #

Исполняющая система ECMAScript производит автоматическое преобразование типов по мере необходимости. Чтобы разъяснить семантику определенных конструкций, полезно определить набор абстрактных операций преобразования. Эти абстрактные операции не являются частью языка. Они определяются в данной спецификации только как вспомогательные средства для определения семантики языка. Абстрактные операции преобразования полиморфны, то есть, они могут принимать значение любого языкового типа, но не типа спецификации.

9.1 ToPrimitive #

Абстрактная операция ToPrimitive К примитиву принимает аргумент input входной и необязательный аргумент PreferredType Предпочтительный тип. Абстрактная операция ToPrimitive преобразует свой аргумент input в тип, не являющийся объектным. Если объект может быть преобразован более чем к одному примитивному типу, то для выбора может быть использована необязательная подсказка PreferredType. Преобразование производится в соответствии с Таблицей 10:

Таблица 10. Преобразования ToPrimitive

Входной тип

Результат

Undefined

Результат равен аргументу input (без преобразования).

Null

Результат равен аргументу input (без преобразования).

Boolean

Результат равен аргументу input (без преобразования).

Number

Результат равен аргументу input (без преобразования).

String

Результат равен аргументу input (без преобразования).

Object

Возвращает значение по умолчанию для Object. Значение по умолчанию какого-либо объекта получается путем вызова внутреннего метода [[DefaultValue]] этого объекта, с передачей необязательной подсказки PreferredType. Описание поведения внутреннего метода [[DefaultValue]] для всех родных объектов ECMAScript приводится в данной спецификации в пункте 8.12.8.

9.2 ToBoolean #

Абстрактная операция ToBoolean К булевому преобразует свой аргумент к значению типа Boolean в соответствии с Таблицей 11:

Таблица 11. Преобразования ToBoolean.

Тип аргумента

Результат

Undefined

false

Null

false

Boolean

Результат равен входному аргументу (без преобразования).

Number

Результат false, если аргумент равен +0, 0 или NaN; в противном случае результат – true.

String

Результат false, если аргумент – пустая строка (длина строки равна нулю); в противном случае результат – true.

Object

true

9.3 ToNumber #

Абстрактная операция ToNumber К числу преобразует свой аргумент к значению типа Number в соответствии с Таблицей 12:

Таблица 12. Преобразования ToNumber

Тип аргумента

Результат

Undefined

NaN

Null

+0

Boolean

Результат равен 1, если аргумент – true. Результат равен +0, если аргумент – false.

Number

Результат равен входному аргументу (без преобразования).

String

См. грамматику и примечание ниже.

Object

Выполняются следующие шаги:

  1. Пусть primValue Примитивное значение будет равно ToPrimitive(входной аргумент, подсказка Number).

  2. Вернуть ToNumber(primValue).

9.3.1 ToNumber применительно к типу String #

Когда ToNumber применяется к строке, эта абстрактная операция применяет к входной строке грамматику, описанную ниже. Если эта грамматика не может интерпретировать строку как развертывание StringNumericLiteral Строковый числовой литерал, то результатом ToNumber будет NaN.

StringNumericLiteral :::

StrWhiteSpaceopt
StrWhiteSpace
optStrNumericLiteral StrWhiteSpaceopt

StrWhiteSpace :::

StrWhiteSpaceChar StrWhiteSpaceopt

StrWhiteSpaceChar :::

WhiteSpace
LineTerminator

StrNumericLiteral :::

StrDecimalLiteral
HexIntegerLiteral

StrDecimalLiteral :::

StrUnsignedDecimalLiteral
+ StrUnsignedDecimalLiteral
- StrUnsignedDecimalLiteral

StrUnsignedDecimalLiteral :::

Infinity
DecimalDigits
. DecimalDigitsoptExponentPartopt
. DecimalDigits ExponentPartopt
DecimalDigits ExponentPart
opt

DecimalDigits :::

DecimalDigit
DecimalDigits DecimalDigit

DecimalDigit ::: один из

0 1 2 3 4 5 6 7 8 9

ExponentPart :::

ExponentIndicator SignedInteger

ExponentIndicator :::один из

e E

SignedInteger :::

DecimalDigits
+ DecimalDigits
- DecimalDigits

HexIntegerLiteral :::

0x HexDigit
0X HexDigit
HexIntegerLiteral HexDigit

HexDigit ::: один из

0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F

Следует обратить внимание на некоторые различия между синтаксисом для StringNumericLiteral и синтаксисом для NumericLiteral (см. 7.8.3):

В целом, преобразование строки в числовое значение аналогично чтению значения типа Number из числового литерала (см. 7.8.3). Однако некоторые моменты отличаются, поэтому здесь мы полностью приводим процесс преобразования строкового числового литерала в значение типа Number. Это значение определяется в два этапа: сначала из строкового числового литерала выводится его математическое значение MV (сокращение от "mathematical value" – прим. перев.), а затем это MV округляется, как описано ниже:

После того, как точное MV строкового числового литерала определено, оно затем округляется до значения типа Number. Если MV равно 0, тогда округленное значение будет +0, за исключением случаев, когда первым непробельным символом в этом строковом числовом литерале является ‘-’, и тогда округленное значение будет 0. В противном случае округленное значение должно представлять собой это числовое значение MV (в соответствии с определением в пункте 8.5), за исключением случаев, когда литерал включает StrUnsignedDecimalLiteral и имеет более 20 значимых чисел – в этом случае числовое значение может быть либо числовым значением MV литерала, полученного при замене на число 0 каждой значащей цифры после 20-й, либо числовым значением MV литерала, полученного в результате замены на число 0 каждой значащей цифры после 20-й, с последующим приращением литерала в позиции 20-й цифры. Цифра является значащей, если она не является частью ExponentPart Экспоненциальная часть, и

9.4 ToInteger #

Абстрактная операция ToInteger К целому преобразует свой аргумент к целочисленному значению. Она действует следующим образом:

  1. Пусть number будет результатом вызова операции ToNumber для входного аргумента.

  2. Если numberNaN, вернуть +0.

  3. Если number равно +0, 0, + или −∞, вернуть number.

  4. Вернуть результат вычисления знак(number) * floor(abs(number)).

9.5 ToInt32: (Знаковое 32-битовое целое) #

Абстрактная операция ToInt32 преобразует свой аргумент к одному из 232 целочисленных значений от 231 до 2311 включительно. Она действует следующим образом:

  1. Пусть number будет результатом вызова операции ToNumber для входного аргумента.

  2. Если number равно NaN, +0, 0, + или −∞, вернуть +0.

  3. Пусть posInt Положительное целое число будет sign(number) * floor(abs(number)).

  4. Пусть int32bit будет posInt modulo 232; то есть – конечным целочисленным значением k типа Number с положительным знаком и меньше 232 по модулю, таким образом, чтобы математическая разность между posInt и k была кратна 232.

  5. Если int32bit больше или равно 231, вернуть int32bit 232, в противном случае – вернуть int32bit.

ПРИМЕЧАНИЕ Принимая во внимание вышеуказанное определение ToInt32:

9.6 ToUint32: (Беззнаковое 32-битовое целое) #

Абстрактная операция ToUint32 преобразует свой аргумент к одному из 232 целочисленных значений от 0 до 2321 включительно. Она действует следующим образом:

  1. Пусть number будет результатом вызова операции ToNumber для входного аргумента.

  2. Если number равно NaN, +0, 0, + или −∞, вернуть +0.

  3. Пусть posInt будет sign(number) * floor(abs(number)).

  4. Пусть int32bit будет posInt modulo 232; то есть – конечным целочисленным значением k типа Number с положительным знаком и меньше 232 по модулю, таким образом, чтобы математическая разность между posInt и k была математически кратна 232.

  5. Вернуть int32bit.

ПРИМЕЧАНИЕ Принимая во внимание вышеуказанное определение ToUInt32:

9.7 ToUint16: (Беззнаковое 16-битовое целое) #

Абстрактная операция ToUint16 преобразует свой аргумент к одному из 216 целочисленных значений от 0 до 2161 включительно. Она действует следующим образом:

  1. Пусть number будет результатом вызова ToNumber для входного аргумента.

  2. Если number равно NaN, +0, 0, + или , то вернуть +0.

  3. Пусть posInt будет sign(number) * floor(abs(number)).

  4. Пусть int16bit будет posInt modulo 216; то есть – конечным целочисленным значением k типа Number с положительным знаком и меньше 216 по модулю, таким образом, чтобы математическая разность между posInt и k была математически кратна 216.

  5. Вернуть intint16bit.

ПРИМЕЧАНИЕ Принимая во внимание вышеуказанное определение ToUint16:

9.8 ToString #

Абстрактная операция ToString К строке преобразует свой аргумент к значению типа String в соответствии с Таблицей 13:

Таблица 13. Преобразования ToString

Тип аргумента

Результат

Undefined

"undefined"

Null

"null"

Boolean

Если аргумент true, то результат – "true".

Если аргумент false, то результат – "false".

Number

См. пункт 9.8.1.

String

Вернуть входной аргумент (без преобразования).

Object

Выполняются следующие шаги:

1. Пусть primValue будет ToPrimitive(входной аргумент, подсказка String).

2. Вернуть ToString(primValue).

9.8.1 ToString применительно к типу Number #

Абстрактная операция ToString преобразует число к строковому формату следующим образом:

  1. Если m равно NaN, вернуть строку "NaN".

  2. Если m равно +0 или 0, вернуть строку "0".

  3. Если m меньше нуля, вернуть строковую конкатенацию строки "-" и ToString(m).

  4. Если m – бесконечность, вернуть строку "Infinity".

  5. В противном случае, пусть n, k и s будут такими целыми числами, чтобы: k 1, 10k1 s < 10k, значение Number для s × 10nk равно m, а k являлось наименьшим возможным числом. Обратите внимание, что k – количество цифр в десятичном представлении s, что s не кратно 10, и что цифра самого младшего разряда в s не обязательно однозначно определяется этими критериями.

  6. Если k n 21, вернуть строку, состоящую из k цифр десятичного представления s (по порядку, без начальных нулей), после которых следуют nk экземпляров символа ‘0’.

  7. Если 0 < n 21, вернуть строку, состоящую из наиболее значимых n цифр десятичного представления s, после которых следует десятичная точка ‘.’, после которой следуют оставшиеся kn цифр десятичного представления s.

  8. Если 6 < n 0, вернуть строку, состоящую из символа ‘0’, после которого следует десятичная точка ‘.’, после которой следуют n экземпляров символа ‘0’, после которых следует k цифр десятичного представления s.

  9. В противном случае, если k = 1, вернуть строку, состоящую из одной цифры из s, после которой следует символ ‘e’ в нижнем регистре, после которого следует знак плюс ‘+’ или знак минус ‘’ (в зависимости от того, является ли n1 положительной или отрицательной величиной), за которой следует десятичное представление целого числа abs(n1) (без начальных нулей).

  10. Вернуть строку, состоящую из старшей цифры десятичного представления s, после которой следует десятичная точка ‘.’, за которой следуют остальные k1 цифр десятичного представления s, после которых следует символ ‘e’ в нижнем регистре, после которого следует знак плюс ‘+’ или знак минус ‘’ (в зависимости от того, является ли n1 положительной или отрицательной величиной), после которого следует десятичное представление целого числа abs(n1) (без начальных нулей).

ПРИМЕЧАНИЕ 1 Следующие наблюдения не являются нормативными требованиями настоящего Стандарта, но могут быть полезны в качестве руководящих принципов для реализаций:

ПРИМЕЧАНИЕ 2 Для реализаций, обеспечивающих более точные преобразования, чем требуют вышеперечисленные правила, рекомендуется в качестве руководящего принципа использовать измененный вариант шага 5:

В противном случае, пусть n, k и s будут такими целыми числами, чтобы: k 1, 10k1 s < 10k, значение Number для s × 10nk равно m, а k являлось наименьшим возможным числом. Если для s есть несколько вариантов, выбрать значение s, для которого s × 10nk является наиболее близким к значению m. Если таких возможных значений s два, выбрать то из них, которое является четным. Обратите внимание, что k – количество цифр в десятичном представлении s, и что s не кратно 10.

ПРИМЕЧАНИЕ 3 Создателям реализаций на ECMAScript советуем ознакомиться с работой и кодом по преобразованию чисел с плавающей точкой из двоичного формата в десятичный, написанными автором David M. Gay:

Gay, David M. Correctly Rounded Binary-Decimal and Decimal-Binary Conversions. Numerical Analysis, Manuscript 90-10. AT&T Bell Laboratories (Murray Hill, New Jersey). November 30, 1990. Эту работу можно найти по адресу
http://cm.bell-labs.com/cm/cs/doc/90/4-10.ps.gz. Используемые коды можно найти по адресу
http://cm.bell-labs.com/netlib/fp/dtoa.c.gz, или по адресу
http://cm.bell-labs.com/netlib/fp/g_fmt.c.gz, а также на различных зеркальных сайтах netlib.

9.9 ToObject #

Абстрактная операция ToObject К объекту преобразует свой аргумент к значению типа Object в соответствии с Таблицей 14:

Таблица 14. ToObject

Тип аргумента

Результат

Undefined

Сгенерировать исключение TypeError.

Null

Сгенерировать исключение TypeError.

Boolean

Создать новый объект Boolean, у которого внутреннему свойству [[PrimitiveValue]] присвоено значение аргумента. Описание объектов Boolean содержится в пункте 15.6.

Number

Создать новый объект Number, у которого внутреннему свойству [[PrimitiveValue]] присвоено значение аргумента. Описание объектов Number содержится в пункте 15.7.

String

Создать новый объект String, у которого внутреннему свойству [[PrimitiveValue]] присвоено значение аргумента. Описание объектов String содержится в пункте 15.5.

Object

Результат равен входному аргументу (без преобразования).

9.10 CheckObjectCoercible #

Абстрактная операция CheckObjectCoercible Проверить приводимость к Object генерирует ошибку, если его аргумент имеет значение, которое невозможно привести к Object посредством операции ToObject. Определение этой операции приводится в Таблице 15.

Таблица 15. Результаты CheckObjectCoercible

Тип аргумента

Результат

Undefined

Сгенерировать исключение TypeError.

Null

Сгенерировать исключение TypeError.

Boolean

Вернуть результат

Number

Вернуть результат

String

Вернуть результат

Object

Вернуть результат

9.11 IsCallable #

Абстрактная операция IsCallable Является вызываемым определяет, является ли аргумент, который должен иметь значение в языке ECMAScript, объектом функции в соответствии с Таблицей 16:

Таблица 16. Результаты IsCallable

Тип аргумента

Результат

Undefined

Вернуть false.

Null

Вернуть false.

Boolean

Вернуть false.

Number

Вернуть false.

String

Вернуть false.

Object

Если у объекта аргумента есть внутренний метод [[Call]], вернуть true, в противном случае вернуть false.

9.12 Алгоритм SameValue #

Абстрактная операция внутреннего сравнения SameValue(x, y) ОдинаковоеЗначение(x, y), где x и y являются значениями ECMAScript, возвращает true или false. Это сравнение производится следующим образом:

  1. Если Type(x) отличается от Type(y), вернуть false.

  2. Если Type(x) – Undefined, вернуть true.

  3. Если Type(x) – Null, вернуть true.

  4. Если Type(x) – Number, то

    1. Если x – NaN и y – NaN, вернуть true.

    2. Если x равно +0 и y равно -0, вернуть false.

    3. Если x равно -0 и y равно +0, вернуть false.

    4. Если x имеет такое же числовое значение, что и y, вернуть true.

    5. Вернуть false.

  5. Если Type(x) – String, то вернуть true, если x и y имеют абсолютно одинаковую последовательность символов (одинаковой длины и с одинаковыми символами в соответствующих позициях), иначе вернуть false.

  6. Если Type(x) – Boolean, вернуть true, одновременно если x и y являются или true, или false; иначе вернуть false.

  7. Вернуть true, если x и y относятся к одному и тому же объекту. Иначе вернуть false.