[英]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
放在一邊,當一個值被強制轉換為基元時, toString
和valueOf
這兩個方法(方法名稱)准備在一個基於類型提示的特定順序。 然后:
- 對於methodNames的每個元素名稱,執行
- 讓方法成為? 獲取( O ,姓名)。
- 如果IsCallable ( method ) 為真,則
這一步是一個循環,遍歷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.