08. Object to Primitive
Бывают операции, при которых объект должен быть преобразован в примитив. Например:
Преобразование в строковый тип — если объект выводится через
alert(obj)
.Преобразование в численный тип — при арифметических операциях, сравнении с примитивом.
Преобразование в логический тип — при
if(obj)
и других логических операциях.
Основные правила:
Любой объект в логическом контексте —
true
, даже если это пустой массив[]
или объект{}
.Само преобразование выполняется по алгоритму
ToPrimitive
.Если на объекте определен символ
@@toPrimitive
, то вызывается он.Для объекта в строковом контексте вызывается метод
toString
.Для численного преобразования объекта используется метод
valueOf
, а если его нет — тоtoString
.
Operation ToPrimitive
ToPrimitive
Converting an arbitrary value to a primitive is handled via the spec-internal operation ToPrimitive(input, ?PreferredType)
takes an with input argument and an optional argument PreferredType
which has three modes:
"number"
: the caller needs a number."string"
: the caller needs a string."default"
: the caller needs either a number or a string. The default mode is only used by:Equality operator (
==
)Addition operator (
+
)new Date(value)
(exactly one parameter!)
If the value is a primitive then ToPrimitive()
is already done. Otherwise, the value is an object obj
, which is converted to a primitive as follows:
Number mode: Return the result of
obj.valueOf()
if it is primitive. Otherwise, return the result ofobj.toString()
if it is primitive. Otherwise, throw aTypeError
.String mode: works like Number mode, but
toString()
is called first,valueOf()
second.Default mode: works exactly like Number mode.
toPrimitive
operation in the spec
toPrimitive
operation in the specThe abstract operation ToPrimitive
converts its input
argument to a non-Object type. If an object is capable of converting to more than one primitive type, it may use the optional hint PreferredType
to favour that type. Conversion occurs according to the following algorithm:
If
Type(input)
isObject
, then:If
PreferredType
was not passed, lethint
be"default"
.Else if
PreferredType
is hintString
, lethint
be"string"
.Else
PreferredType
is hintNumber
, lethint
be"number"
.Let
exoticToPrim
be ?GetMethod(input, @@toPrimitive)
.If
exoticToPrim
is notundefined
, thenLet
result
beCall(exoticToPrim, input, hint)
.If
Type(result)
is notObject
, returnresult
.Throw a
TypeError
exception.
If hint is
"default"
, set hint to"number"
.Return
OrdinaryToPrimitive(input, hint)
.
Return
input
.
When the abstract operation OrdinaryToPrimitive(O, hint)
is called with arguments O
and hint
, the following steps are taken:
Assert:
Type(O)
isObject
.Assert:
Type(hint)
isString
and its value is either"string"
or"number"
.If
hint
is"string"
, then:Let
methodNames
be["toString", "valueOf"]
.
Else,
Let
methodNames
be["valueOf", "toString"]
.
For each name in
methodNames
doLet method be
Get(O, name)
.If
IsCallable(method)
istrue
, thenLet
result
beCall(method, O)
.If
Type(result)
is notObject
, returnresult
.
Throw a
TypeError
exception.
Symbol @@toPrimitive
@@toPrimitive
Symbol.toPrimitive
lets an object customize how it is coerced (converted automatically) to a primitive value. Значением этого символа должна быть функция, возвращающая значение одного из примитивных типов. Эта функция вызывается в качестве первой при преобразовании объекта в примитив по алгоритму ToPrimitive
и имеет приоритет над другими функциями преобразования.
Operations toString
and valueOf
toString
and valueOf
Все объекты наследуют два метода преобразования:
Метод
toString()
он возвращает строковое представление объекта. Если переменная является объектом, то по умолчанию методtoString
выводит[object <Tип>]
. Обратиться к этой нативной реализацииtoString
можноObject.prototype.toString.call(obj)
.Метод
valueOf()
. Задача этого метода определена нечетко: предполагается, что он должен преобразовать объект в представляющее его простое значение, если такое значение существует. Объекты по своей природе являются составными значениями, и большинство объектов не могут быть представлены в виде единственного простого значения, поэтому по умолчанию методvalueOf()
возвращает не простое значение, а сам объект (this
). МетодvalueOf
обязан возвращать примитивное значение, иначе его результат будет проигнорирован. При этом — не обязательно числовое.
Примеры использования valueOf
:
Классы-обертки определяют методы
valueOf()
, возвращающие обернутые простые значения.Массивы, функции и регулярные выражения наследуют метод по умолчанию. Вызов метода
valueOf()
экземпляров этих типов возвращает сам объект.Класс
Date
определяет методvalueOf()
, возвращающий дату во внутреннем представлении: количество миллисекунд, прошедших с 1 января 1970 года.
Last updated
Was this helpful?