簡體   English   中英

當對象添加到數字時,為什么JS調用`toString`方法

[英]Why does JS call `toString` method when object is added to a number

我知道當JS嘗試將對象表示為原始對象時,它會在對象上調用valueOf方法。 但今天我發現它也在同樣的情況下調用toString()方法:

var o = {};
o.toString = function() {return 1};
1+ o; // 2

為什么? 如果我添加valueOf方法,則不調用toString

我想這個解釋在ECMA-262規范的 8.6.2.6章節中:

8.6.2.6 [DefaultValue]

[...]

使用提示號調用O的[[DefaultValue]]方法時,將執行以下步驟:

  1. 使用參數“valueOf”調用對象O的[[Get]]方法。

  2. 如果Result(1)不是對象,請轉到步驟5。

  3. 調用Result(1)的[[Call]]方法,O為該值,空參數列表。
  4. 如果Result(3)是原始值,則返回Result(3)。

  5. 使用參數“toString”調用對象O的[[Get]]方法。

  6. 如果Result(5)不是對象,請轉到步驟9。

  7. 調用Result(5)的[[Call]]方法,使用O作為此值和空參數列表。
  8. 如果Result(7)是原始值,則返回Result(7)。
  9. 生成運行時錯誤。 當沒有提示調用O的[[DefaultValue]]方法時,它的行為就好像提示是Number,除非O是Date對象(參見15.9節),在這種情況下,它的行為就像提示是String一樣。

由於您的對象未實現valueOf,因此使用toString。

這一切都取決於提示。 當你使用1 + o它是一個數字提示,因為+操作數所以它肯定會在toString之前使用valueOf

如果提示是String,則在valueOf之前使用toString 例如試試["o",o].join("=")

一起將是:

var o = {};
o.toString = function() {return 1};
o.valueOf= function(){return 2};
1 + o; // 1+2=3 ==> it takes valueOf value
["o",o].join("") //o1 ==> it takes toString value

TL; DR

在沒有hint情況下調用ToPrimitive時,它就像提示是number 它定義了要調用的方法:first valueOf然后toString 如果你還沒有定義自己的valueOf它會調用返回它的Object.prototype.valueOf

BTW在現代瀏覽器中你可以更具體地了解它

const a = {
   [Symbol.toPrimitive]: function(hint) {
       console.log(hint);
       return {
          'default': 1,
          'number': 2,
          'string': 'three'
       }[hint]
   }
}

console.log(a + 1); //default, 2
console.log(+a + 1); //number, 3
console.log(`${a} + one`); //string, three + one

長讀:

  1. 加成
  2. ToPrimitive

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM