js|js 中的不同的数据类型之间作比较时的“隐式转换规则”(详细!!!)

一、js 隐式转换规则 1. javascript 隐式转换规则
隐式类型转换是在一定场景下,js 运行环境自动调用这几个方法,尝试转换成期望的数据类型

  • ToString
  • ToNumber
  • ToBoolean
  • ToPrimitive
注:有关 javascript 隐式转换规则详情,可参考 Javascript基础:隐式类型转换
2.两个数据比较的情况
两个数据比较时,如果两边数据不是同种类型的话,按以下规则进行相应的隐式类型类型转换
  • 对象 --> 字符串 --> 数值
  • 布尔值 --> 数值
注:有关两个数据相加的情况,可参考 “加号 +” 的运算原理(详细!!!);
??有关隐式转换规则的坑点详细分析,可参考 js面试题大坑——隐式类型转换

二、具体分析(六种基本情况 + 三种特殊情况) 1. 对象和字符串比较
① 说明 隐式转换规则:调用 ToPrimitive() 内部函数,将对象转换为字符串,然后两者进行比较。
注:在 js 中,想要将对象转换成原始值,必然会调用 toPrimitive() 内部函数。
??① 有关 ToPrimitive() 方法,可参考 JS原始值转换算法—toPrimitive()
??① 有关 valueOf() 方法,可参考 JS 中 valueOf() 方法的详解
??① 有关 toString() 方法,可参考 有关 toString() 方法的初步认识

② 示例
// 数组(Array)对象和字符串比较 [1,2,3] == '1,2,3' // true

隐式转换过程:
  • 对左边的数组对象进行隐式转换 ToPrimitive([1,2,3]) -> '1,2,3'
  • 然后和右边的 '1,2,3' 比较,易得结果为 true
// Object 对象和字符串比较 let obj = { a:1} obj == '[object Object]' // true

隐式转换过程:
  • 对左边的数组对象进行隐式转换 ToPrimitive([1,2,3]) -> '[object Object]'
  • 然后和右边的 '[object Object]' 比较,易得结果为 true
2. 对象和数值比较
① 说明 隐式转换规则:调用 ToPrimitive() 内部函数,将对象转换为字符串,再调用 ToNumber() 将字符串转换为数字,然后两者进行比较。
ToNumber(argument) 转换方式:
argument类型 返回值
Undefined return NaN
Null return 0
Boolean true return 1; false return 0;
Number return value
String 若字符串为纯数字,返回转换后的数字;空字符则返回 0;非纯数字则返回 NaN
Symbol 抛出 TypeError 异常
Object 进行如右步骤:1.先进行 ToPrimitive(argument, hint Number) 得到 rs ;?2.然后返回 ToNumber(rs) 的结果。
② 示例
// 数组(Array)对象和数值比较 [11] == 11 // true

隐式转换过程:
  • 对象转换为字符串 ToPrimitive([11]) -> '11'
  • 字符串转换为数字 ToNumber('11') -> 11
  • 然后和右边的 11 比较,易得结果为 true
3. 对象和布尔值比较
① 说明 隐式转换规则:
??调用 ToPrimitive() 内部函数,将对象转换为字符串,再调用 ToNumber() 将字符串转换为数字;
??调用 ToNumber() 将布尔值转换为数字;
??然后两者进行比较。

ToNumber(argument) 转换方式:
argument类型 返回值
String 若字符串为纯数字,返回转换后的数字;空字符则返回 0;非纯数字则返回 NaN
Boolean true return 1; false return 0;
② 示例
// 数组(Array)对象和布尔值比较 [] == false // true

左边数据的隐式转换过程:
  • 对象转换为字符串 ToPrimitive([]) -> ''
  • 字符串转换为数字 ToNumber('') -> 0
右边数据的隐式转换过程:
  • 布尔值转换为数字 ToNumber(false) -> 0
  • 两边比较,易得结果 true
4. 字符串和数值比较
① 说明 隐式转换规则:
??调用 ToNumber() 将字符串转换为数字,然后两者进行比较。

【js|js 中的不同的数据类型之间作比较时的“隐式转换规则”(详细!!!)】ToNumber(argument) 转换方式:
argument类型 返回值
String 若字符串为纯数字,返回转换后的数字;空字符则返回 0;非纯数字则返回 NaN
② 示例
// 数组(Array)对象和布尔值比较 '11' == 11 // true

隐式转换过程:
  • 字符串转换为数字 ToNumber('11') -> 11
  • 两边比较,易得结果 true
5. 字符串和布尔值比较
① 说明 隐式转换规则:
??调用 ToNumber() 将字符串转换为数字;
??调用 ToNumber() 将布尔值转换为数字;
??然后两者进行比较。

ToNumber(argument) 转换方式:
argument类型 返回值
String 若字符串为纯数字,返回转换后的数字;空字符则返回 0;非纯数字则返回 NaN
Boolean true return 1; false return 0;
② 示例
// 数组(Array)对象和布尔值比较 '1' == true // true

左边数据的隐式转换过程:
  • 字符串转换为数字 ToNumber('1') -> 1
右边数据的隐式转换过程:
  • 布尔值转换为数字 ToNumber(true) -> 1
  • 两边比较,易得结果 true
6. 布尔值和数值比较
① 说明 隐式转换规则:
??调用 ToNumber() 将布尔值转换为数字,然后两者进行比较。

ToNumber(argument) 转换方式:
argument类型 返回值
Boolean true return 1; false return 0;
② 示例
// 数组(Array)对象和布尔值比较 1 == true // true

隐式转换过程:
  • 布尔值转换为数字 ToNumber(true) -> 1
  • 两边比较,易得结果 true
7. 存在 !运算符(特殊情况一)
① 说明 隐式转换规则:
??若某数据前面存在 !运算符,则先将该数据转换为布尔值,其余的按照上述规则进行。

注:除 0NaN''nullundefined 转换为布尔值为 false 外,其余数据转换为布尔值均为 true。此外,还应关注一下一些特殊数。
console.log( ! 0 ); // true console.log( ! NaN ); // true console.log( ! '' ); // true console.log( ! null ); // true console.log( ! undefined ); // true console.log( ! [] ); // false console.log( ! { } ); // false console.log( ! Infinity ); // false console.log( ! ( - Infinity )); // false

② 示例
[] == false; // true

见第 3 点 “对象和布尔值比较” 的分析
![] == false; // true

隐式转换过程:
  • 由于存在 ! 运算符,故直接将 [] 转换为布尔值 true,则 ![],为 false
  • 两边比较,易得结果为 true
8. null 和 undefined 的比较(特殊情况二)
① 说明
  • 实际上,undefined 值是派生自 null 值的,ECMAScript 标准规定对二者进行相等性测试要返回 true,可以理解为 null 和 undefined 都代表着无效的值,所以二者相等,但由于是两种不同的原始数据类型,所以不全等。
  • 除此之外其他的类型的值与它们都不相等。
注:有关 null 和 undefined 的详情和区别,可参考 JS 中的 undefined 和 null 的区别
② 示例
undefined == null // true undefined === null // false

9. 存在 NaN(特殊情况三)
① 说明
  • NaN(Not a Number)表示一个非数字,但数据类型确是 Number 类型
  • NaN 是 JavaScript 之中唯一不等于自身的值,不等于任何值,包括它本身
② 示例
NaN == NaN // false

    推荐阅读