JavaScript 物件轉換到基本型別值演算法 ToPrimitive

zhangbao90s發表於2018-01-25

JavaScript 物件什麼場景下會轉換到基本型別值呢?

  1. 數學運算:obj1 + obj2obj1 - obj2 等。
  2. 期望值是基本型別值的運算:alert(obj)

ToPrimitive 演算法

JavaScript 物件轉換到基本型別值時,會使用 ToPrimitive 演算法,這是一個內部演算法,是程式語言在內部執行時遵循的一套規則。

hint

ToPrimitive 演算法在執行時,會被傳遞一個引數 hint,表示這是一個什麼型別的運算(也可以叫運算的期望值),根據這個 hint 引數,ToPrimitive 演算法來決定內部的執行邏輯。

hint 引數的取值只能是下列 3 者之一:

  • string
  • number
  • default

轉換演算法

當物件發生到基本型別值的轉換時,會按照下面的邏輯呼叫物件上的方法:

  1. 如果存在,呼叫 obj[Symbol.toPrimitive](hint)
  2. 否則,如果 hint 取值是 "string"
    • 無論是否存在,呼叫 obj.toString()obj.valueOf()
  3. 否則(也就是 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.toPrimitivetoString/valueOf 方法必須返回 hint 引數值所暗示的型別值。

但要注意下面兩點:

  1. Symbol.toPrimitivetoString 方法的返回值必須是基本型別值。
  2. valueOf 方法除了可以返回基本型別值,也可以返回其他型別值。

其他

當我們建立一個普通物件時({}new Object() 的方式等),物件上是不具備 [Symbol.toPrimitive] (方法)屬性的。所以,對於普通物件的到基本型別值的運算,一般按照具體場景:

  1. hint 值為 "string" 時,先呼叫 toStringtoString 如果返回一個基本型別值了,則返回、終止運算;否則接著呼叫 valueOf 方法。
  2. 否則,先呼叫 valueOfvalueOf 如果返回一個基本型別值了,則返回、終止運算;否則接著呼叫 toString 方法。

(完)

相關文章