JS引用类型在隐式类型转换时到底做了什么

1 前言

在实际开发中,比较运算符和全等运算符都是被高频应用的点
在两边类型不同的情况下,比较运算符得到的是隐式类型转换之后的比较结果

但是引用类型在隐式类型转换时存在一些坑点,在实际开发中稍不注意就会出现bug
比如:

[] == 0 // true

因此不妨了解底层到底做了什么

2 引用类型与基本数据类型的转换

隐式转换时,一般都是引用类型转换成基本数据类型,再进行比较
转换的目的只有一个:得到基本数据类型,或者说原始值

引用数据类型在转换时一般会用到两个API: valueOf与toString

  • valueOf方法用于将对象转换为原始值。如果对象没有原始值,则valueOf将返回对象本身。你很少需要自己调用valueOf方法;当遇到要预期的原始值的对象时,JavaScript会自动调用它
  • toString方法返回一个表示该对象的字符串

2.1 对象转字符串

重写原型的valueOf和toString简单验证一下,时间有限,逻辑可能并不完全严密,有时间的可以按照思路多写点case补充看看

const log = console.log
Object.prototype.toString = () => 'a'
Object.prototype.valueOf = () => 'b'
log(Object() == 'a') // false
log(Object() == 'b') // true

Object.prototype.toString = () => 'a'
log(Object() == 'a') // true

先调用valueOf再调用toString

2.2 对象转数字

Object.prototype.toString = () => 1
Object.prototype.valueOf = () => 2
log(Object() == 1)
log(Object() == 2) // true

先调用valueOf再调用toString

2.3 数组转字符串

Array.prototype.toString = () => 'a'
Array.prototype.valueOf = () => 'b'
log([] == 'a') // false
log([] == 'b') // true

先调用valueOf再调用toString

Array.prototype.join = () => 'a'
log([] == 'a') // true

底层调用的是join

到了这一步,关于文章开头所提到的 [] == 0 为true就很好理解了

  1. 检测到引用类型和基本类型做比较运算,于是js将引用类型隐式转换成基本类型再进行比较
  2. 隐式转换时,首先调用valueOf,又因为是数组,所以在valueOf中返回join方法的执行结果
  3. 问题变成了熟悉的 ‘’ == 0 , 返回true

3 总结

引用类型转基本类型,目的是拿到原始值,底层都是先调用valueOf再调用toString
过程中,如果任意一个方法拿到原始值就返回,否则继续下一个方法
如果始终没有拿到原始值,那么抛出异常

猜你喜欢

转载自blog.csdn.net/qq_41109610/article/details/114242676