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: number
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
方法。
(完)