簡體   English   中英

如果 `toString` 返回非原始類型,它會被“忽略”是什么意思?

[英]What does it mean that `toString` gets “ignored” if it returns a non-primitive?

Object.prototype.toString上的 MDN 文檔說,當toString被覆蓋時,它應該只返回一個原始值:

您創建的toString() function 必須返回一個原語,否則將被忽略。

但是,在下面的示例中,我們在toString內部返回一個 object,它正常返回 object:

 const ob2 = { val1: 100, val2: 200, toString: function() { return { veh: "meh" }; // Object. } }; console.log(ob2.toString());

Output:

{ veh: "meh" }

所以toString方法正常返回object。 錯誤信息是怎么回事?

你是對的,文檔具有誤導性和不完整。 我已經提交了一個pull request ,改寫如下:

刪除了這部分:

您創建的toString() function 必須返回一個原語,否則將被忽略。

取而代之:

您創建的toString() function 必須返回一個原語。 如果它返回一個 object 並且該方法被隱式調用(即在類型轉換或強制轉換期間),那么它的結果將被忽略並且將使用相關方法的值valueOf() ,否則將拋出一個TypeError如果這些方法都不返回原語。


我找到了添加此措辭的原始拉取請求提交 參考這句話,作者有評論評論說:

請參閱步驟 5.B.ii 來自https://262.ecma-international.org/9.0/#sec-ordinarytoprimitive

作者所指的是規范中OrdinaryToPrimitive抽象操作的結果:將Symbol.toPrimitive放在一邊,當一個值被強制轉換為基元時, toStringvalueOf這兩個方法(方法名稱)准備在一個基於類型提示的特定順序。 然后:

  1. 對於methodNames的每個元素名稱,執行
    1. 方法成為? 獲取O姓名)。
    2. 如果IsCallable ( method ) 為,則
      1. 結果如何? 調用方法O )。
      2. 如果Type (result) 不是 Object,則返回result

這一步是一個循環,遍歷methodNames列表。 它從該列表中獲取下一個方法,檢查它是否為 function,調用它,並將其結果存儲在result中。 然后它執行類型檢查。 如果結果是原語,即不是 object,則返回此結果。 否則,循環繼續,有效地忽略結果

如果循環到達結尾而沒有返回值,則會拋出 TypeError。

為了演示此行為,您必須同時擁有這兩種方法:

 class Test1 { toString() { return "1"; } valueOf() { return "2"; } } class Test2 { toString() { return {}; } valueOf() { return "2"; } } class Test3 { toString() { return "1"; } valueOf() { return {}; } } class Test4 { toString() { return {}; } valueOf() { return {}; } } const test1 = new Test1, test2 = new Test2, test3 = new Test3, test4 = new Test4; console.log(String(test1)); // "1"; toString is preferred. // `"" + test1` and `+test1` also demonstrate this. console.log(Number(test1)); // 2; valueOf is preferred. console.log(String(test2)); // "2"; toString is ignored; valueOf is chosen instead. console.log(Number(test2)); // 2; valueOf is preferred. console.log(String(test3)); // "1"; toString is preferred. console.log(Number(test3)); // 1; valueOf is ignored; toString is chosen instead. console.log(String(test4)); // TypeError; none of the methods returns a primitive. console.log(Number(test4)); // TypeError; none of the methods returns a primitive.


文檔沒有提到的是顯式調用toString方法,因為它工作得很好:

 class Test { toString() { return { hello: "world" }; } } const test = new Test; console.log(test.toString()); // Logs { hello: "world" }.

暫無
暫無

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

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