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

Posted C澒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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类型返回值
Undefinedreturn NaN
Nullreturn 0
Booleantrue return 1; false return 0;
Numberreturn 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
Booleantrue return 1; false return 0;

② 示例

	// 数组(Array)对象和布尔值比较
	[] == false	// true  

左边数据的隐式转换过程:

  • 对象转换为字符串 ToPrimitive([]) -> ''
  • 字符串转换为数字 ToNumber('') -> 0

右边数据的隐式转换过程:

  • 布尔值转换为数字 ToNumber(false) -> 0
  • 两边比较,易得结果 true

4. 字符串和数值比较

① 说明

隐式转换规则:
  调用 ToNumber() 将字符串转换为数字,然后两者进行比较。

ToNumber(argument) 转换方式:

argument类型返回值
String若字符串为纯数字,返回转换后的数字;空字符则返回 0;非纯数字则返回 NaN

② 示例

	// 数组(Array)对象和布尔值比较
	'11' == 11	// true  

隐式转换过程:

  • 字符串转换为数字 ToNumber('11') -> 11
  • 两边比较,易得结果 true

5. 字符串和布尔值比较

① 说明

隐式转换规则:
  调用 ToNumber() 将字符串转换为数字;
  调用 ToNumber() 将布尔值转换为数字;
  然后两者进行比较。

ToNumber(argument) 转换方式:

argument类型返回值
String若字符串为纯数字,返回转换后的数字;空字符则返回 0;非纯数字则返回 NaN
Booleantrue return 1; false return 0;

② 示例

	// 数组(Array)对象和布尔值比较
	'1' == true	// true  

左边数据的隐式转换过程:

  • 字符串转换为数字 ToNumber('1') -> 1

右边数据的隐式转换过程:

  • 布尔值转换为数字 ToNumber(true) -> 1
  • 两边比较,易得结果 true

6. 布尔值和数值比较

① 说明

隐式转换规则:
  调用 ToNumber() 将布尔值转换为数字,然后两者进行比较。

ToNumber(argument) 转换方式:

argument类型返回值
Booleantrue 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

以上是关于js 中的不同的数据类型之间作比较时的“隐式转换规则”(详细!!!)的主要内容,如果未能解决你的问题,请参考以下文章

js基础知识 ==操作符

删除 Vue JS 中的元素时在 dev 中工作但在 prod 中不工作时的动画

PySpark DataFrames - 使用不同类型的列之间的比较进行过滤

js中的“==”和“===”的区别

JS 之 数据类型转换

JS基础类型转换——不同数据类型比较