Javascript的toPrimitive valueOf toString

72 阅读3分钟

Javascript的引用类型的隐式类型转换的过程

什么是隐式类型转换

javascript中的引用类型的隐式转换一直是比较困扰开发者的一个问题

其中最常见的引用类型的隐式转换是发生在使用==符号和引用类型和基础类型相加时

const obj={}

//引用类型和基础类型相加时
console.log(obj+'');

//使用 == 时
console.log(obj==22);

我们都知道js在使用 == 符号进行比较时需要把两边的数据类型进行转换为同一个数据类型再进行变量值上的比较

比如,在下面两个基础类型的booleannumber的比较

console.log(true==2);

我们都知道js会把true转换为number数据类型再进行比较,其实这就是隐式类型转换

在不同的类型的变量进行相加时也是会出现隐式类型转换

引用类型的隐式类型转换的三个函数

在我们使用引用类型于基础类型相加时,引用类型变量会先转换成基础类型在进行比较

那它是如何转换的 ?转换成什么值 ?

其实这一切都取决于对象(数组也是对象)中的三个内置函数

  • Object[Symbol.toPrimitive]
  • Object.valueOf
  • Object.obj.toString()

我们来简明说一下当引用类型转换成基础类型的过程

  1. 首先js会先找到对象的[Symbol.toPrimitive]函数,看其是否存在,如果不存在则进入下一步,存在的话有下面两种情况
    • 如果[Symbol.toPrimitive]函数返回基础类型的数据,则以此值为结果,转换结束
    • 如果[Symbol.toPrimitive]函数返回引用类型数据,则报错,转换失败
  2. [Symbol.toPrimitive]不存在的话会找到对象中的 valueOf 函数,分下面三种情况
    • 如果 valueOf 函数不存在,则进入下一步
    • 如果 valueOf 函数返回值为引用类型,则进入下一步
    • 如果 valueOf 函数没有返回值,则转换结果为 undefined,转换结束
    • 如果 valueOf 函数返回值为基础类型数据,则以此值为结果,转换结束
  3. 到这一步后,js会找到对象中的 toString 函数,分
    • 如果 toString 函数没有返回值,则转换结果为 undefined,转换结束
    • 如果 toString 函数返回值为基础类型数据,则以此值为结果,转换结束
    • 如果 toString函数返回值为引用类型,则报错,转换失败

例子

我们回到上面的代码中

const obj={}

//引用类型和基础类型相加时
console.log(obj+'');

//使用 == 时
console.log(obj==1);

我们定义了一个空对象进行了与空字符的相加和与数值 1 的比较

在进行这两个操作时,obj 它会转换成基础类型

我们试着让 obj==1 成立

  const obj={}

  obj[Symbol.toPrimitive]=()=>1
  
  console.log(obj==1);   //  值为 true

还有以下情况 也可行

  const obj={}

  // obj[Symbol.toPrimitive]=()=>1   [Symbol.toPrimitive]此时没有这个函数
  
  obj.valueOf=()=>1
  
  obj.toString=()=>'1111111111111'

  console.log(obj==1);     //  值还是  true

还有很多很多情况,只要理解三个函数的优先级和不同情况下的操作