JavaScript 对象什么场景下会转换到基本类型值呢?
- 数学运算:
obj1 + obj2
、obj1 - obj2
等。 - 期望值是基本类型值的运算:
alert(obj)
。
ToPrimitive 算法
JavaScript 对象转换到基本类型值时,会使用 ToPrimitive 算法,这是一个内部算法,是编程语言在内部执行时遵循的一套规则。
hint
ToPrimitive 算法在执行时,会被传递一个参数 hint
,表示这是一个什么类型的运算(也可以叫运算的期望值),根据这个 hint
参数,ToPrimitive 算法来决定内部的执行逻辑。
hint
参数的取值只能是下列 3 者之一:
string
number
default
转换算法
当对象发生到基本类型值的转换时,会按照下面的逻辑调用对象上的方法:
- 如果存在,调用
obj[Symbol.toPrimitive](hint)
; - 否则,如果
hint
取值是"string"
:- 无论是否存在,调用
obj.toString()
和obj.valueOf()
。
- 无论是否存在,调用
- 否则(也就是
hint
取值是"number"
或"default"
的情况):- 无论是否存在,调用
obj.valueOf()
和obj.toString()
。
- 无论是否存在,调用
确定 hint
我们提到了 ToPrimitive 算法中用到的 hint
参数,那怎样确定一次运算场景下的 hint
取值是什么呢?很简单----新建一个对象,打印各个运算场景下的 hint
值:
let user = {
name: "John",
money: 1000,
[Symbol.toPrimitive](hint) {
console.log(`hint: ${hint}`);
}
};
alert(user) // hint: string
+user // hint: default
user + 500 // hint: default
Symbol.toPrimitive 和 toString/valueOf 方法
并不要求 Symbol.toPrimitive
和 toString/valueOf
方法必须返回 hint
参数值所暗示的类型值。
但要注意下面两点:
Symbol.toPrimitive
和toString
方法的返回值必须是基本类型值。valueOf
方法除了可以返回基本类型值,也可以返回其他类型值。
其他
当我们创建一个普通对象时({}
或 new Object()
的方式等),对象上是不具备 [Symbol.toPrimitive]
(方法)属性的。所以,对于普通对象的到基本类型值的运算,一般按照具体场景:
hint
值为"string"
时,先调用toString
,toString
如果返回一个基本类型值了,则返回、终止运算;否则接着调用valueOf
方法。- 否则,先调用
valueOf
,valueOf
如果返回一个基本类型值了,则返回、终止运算;否则接着调用toString
方法。
(完)