JavaScript高阶教程之“==”隐藏下的类型转换(3)

const obj = { toString(){ console.log('调用了toString'); return {}; }, valueOf(){ console.log('调用了valueOf'); return {}; } } console.log(String(obj)); 控制台输出结果: >>>>>>>>>>>>>>>>>> 调用了toString 调用了valueOf Uncaught TypeError: Cannot convert object to primitive value

我们又发现:

在ToString情况下,如果toString和valueOf返回的都不是原始数据类型,那么js会抛出异常,提示无法将引用类型转换原始数据类型。

我们将三个结论综合一下:

在ToString情况下,js会优先调用toString,如果toString返回的不是原始数据类型,则会接着调用valueOf,如果valueOf返回的也不是原始数据类型,js会抛出一个异常,提示无法将引用类型转换原始数据类型。

具体流程图如下:

JavaScript高阶教程之“==”隐藏下的类型转换


“==”下的valueOf和toString的优先级

从文章前面我们总结出来“==”的比较流程来看,引用类型转换成原始数据类型之后,如果是Sting类型的话,还要再次转成Number类型,因此“==”下的引用类型转换原始数据类型过程中,遵循ToNumber的优先级规则。

const obj = { toString(){ console.log('调用了toString'); return 'Hello,Teacher Cang!'; }, valueOf(){ console.log('调用了valueOf'); return 12345; } } console.log(obj==12345); 控制台输出结果: >>>>>>>>>>>>>>>>>> 调用了valueOf true

const obj = { toString(){ console.log('调用了toString'); return 12345; }, valueOf(){ console.log('调用了valueOf'); return {}; } } console.log(obj==12345); 控制台输出结果: >>>>>>>>>>>>>>>>>> 调用了valueOf 调用了toString true

const obj = { toString(){ console.log('调用了toString'); return {}; }, valueOf(){ console.log('调用了valueOf'); return {}; } } console.log(obj==12345); 控制台输出结果: >>>>>>>>>>>>>>>>>> 调用了toString 调用了valueOf Uncaught TypeError: Cannot convert object to primitive value

“==”之外的类型转换

“==”号只涉及到了ToPrimitive和ToNumber这两种转换,ToBoolean和ToString这两个没有涉及到的我们也介绍一下。

ToBoolean

对于ToBoolean,我们只需要记住几个特例是转成false的,其余的皆为true。

Boolean('') => false Boolean(undefined) => false Boolean(null) => false Boolean(0) => false

ToString

Number to String

Number转String之前,首先会做一个去0和补0的操作,然后再去转成String类型。

String(1.234) => "1.234" String(NaN) => "NaN" String(.1234) => "0.1234" String(1.23400) => "1.234"

Boolean to String

String(true) => "true" String(false) => "false"

null和undefined to String

String(null) => "null" String(undefined) => "undefined"

引用类型 to String

引用类型先ToPrimitive转换成原始数据类型,若转换后的原始数据类型不是String类型,再做String类型的转换。

const obj = { toString(){ console.log('调用了toString'); return true; } } console.log(String(obj)) 控制台输出结果: >>>>>>>>>>>>>>>>>> 调用了toString "true"

总结

“==”下的类型转换,要分为两种情况来考虑。第一种,原始数据类型;第二种,引用类型。原始数据类型中String类型和Boolean类型是需要转换成Number类型再去比较的,而引用类型则需要先转换成原始数据类型再进行后续的转换。搞清整个流程之后,我们再去理解“==”涉及到的ToNumber和ToPrimitive是如何进行转换的。按照这样子的理解步骤走,我们对“==”隐藏下的类型转换会有比较清晰的认识。另外,“==”不涉及到ToString和ToBoolean的类型转换,在文章的后面部分我也加上去了,希望可以给小伙伴们一个更加全面的类型转换的认识。最后附上完整的“==”类型转换的流程图:

JavaScript高阶教程之“==”隐藏下的类型转换

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/30f8a7dbe57480058a1f954ed355664a.html