const obj = { toString(){ console.log('调用了toString'); return 'Hello,Teacher Cang!'; }, valueOf(){ console.log('调用了valueOf'); return 12345; } } console.log(Number(obj)); 控制台输出结果: >>>>>>>>>>>>>>>>>> 调用了valueOf 12345
通过上面的代码的运行结果,我们得出这么一个结论:
在ToNumber情况下,valueOf的优先级大于toString。
接下里我们看这么一种情况,如果valueOf返回的并不是原始数据类型会怎么样。
const obj = { toString(){ console.log('调用了toString'); return 12345; }, valueOf(){ console.log('调用了valueOf'); return {}; } } console.log(Number(obj)); 控制台输出结果: >>>>>>>>>>>>>>>>>> 调用了valueOf 调用了toString 12345
从上面的运行结果中,我们可以得出这么一个结论:
在ToNumber情况下,如果valueOf返回的不是原始数据类型,则会自动调用toString。
打破砂锅问到底,再来一个非常极端的情况,如果说valueOf和toString返回的都不是原始数据类型,这时又该怎么样呢?同样,我们继续看一下运行结果:
const obj = { toString(){ console.log('调用了toString'); return {}; }, valueOf(){ console.log('调用了valueOf'); return {}; } } console.log(Number(obj)); 控制台输出结果: >>>>>>>>>>>>>>>>>> 调用了valueOf 调用了toString Uncaught TypeError: Cannot convert object to primitive value
从上面的运行结果中,我们再次可以得出这么一个结论:
在ToNumber情况下,如果valueOf和toString返回的都不是原始数据类型,那么js会抛出异常,提示无法将引用类型转换原始数据类型。
根据三组代码的运行的结果,我们最后总结一下:
在ToNumber情况下,js会优先调用valueOf,如果valueOf返回的不是原始数据类型,则会接着调用toString,如果toString返回的也不是原始数据类型,js会抛出一个异常,提示无法将引用类型转换原始数据类型。
具体流程图如下:
ToString
看个栗子🌰:
const obj = { toString(){ console.log('调用了toString'); return 'Hello,Teacher Cang!'; }, valueOf(){ console.log('调用了valueOf'); return 12345; } } console.log(String(obj)); 控制台输出结果: >>>>>>>>>>>>>>>>>> 调用了toString Hello,Teacher Cang!
通过上面的代码的运行结果,我们得出这么一个结论:
在ToString情况下,toString的优先级大于valueOf。
同样我们看一下,toString返回的值不是原始数据类型时会怎样:
const obj = { toString(){ console.log('调用了toString'); return {}; }, valueOf(){ console.log('调用了valueOf'); return 'Hello,Teacher Cang!'; } } console.log(String(obj)); 控制台输出结果: >>>>>>>>>>>>>>>>>> 调用了toString 调用了valueOf Hello,Teacher Cang!
根据运行结果我们可以得出:
在ToString情况下,如果toString返回的不是原始数据类型,则会自动调用valueOf。
最后我们看一下极端情况,二者返回的都不是原始数据类型: