内容简介:很多人包括我在内很抵触这种问题:rage:,因为很长一段时间我一直弄不明白 == 和 === 到底是怎么个规则。如果你也没闹明白 == 和 ===,读了这篇文章应该至少不会见到这俩操作符就觉得恶心了吧 。另外需要注意的是,== 的英文名叫 Abstract Equality Comparison;=== 则是 Strict Equality Comparison。废话不多说,我们开始搞起
图解 == 操作符规则和不同类型间转换规则
很多人包括我在内很抵触这种问题:rage:,因为很长一段时间我一直弄不明白 == 和 === 到底是怎么个规则。如果你也没闹明白 == 和 ===,读了这篇文章应该至少不会见到这俩操作符就觉得恶心了吧 。
另外需要注意的是,== 的英文名叫 Abstract Equality Comparison;=== 则是 Strict Equality Comparison。
废话不多说,我们开始搞起
== 操作符
== 操作符基本规则
首先需要注意的是
- 如果要比较的两个项是同种类型的,那么 == 就会返回 === 操作符的执行结果。举个例子:chestnut:
2 == 3
最后会返回2 === 3
的执行结果 - 如果要比较的两个项是不同类型的,== 就会对其中一个或两者都进行类型转换然后再比较。比如
2 == '3'
就会变成2 == 3
最后会比较2 === 3
这就是最基本的规则
== 操作符具体的转化规则
然后我们再来看看具体的转换规则:arrow_down::
整体流程概览
- 如果类型相同,调用
===
操作符 -
如果类型不同,尝试类型转换
-
- 查看是否是
undefined
和null
比较
true
- 查看是否是
-
- 是否在比较
string
和number
- :white_check_mark: 如果是,那么将
string
转为number
并回到最初重新比较 :recycle: - :arrow_down: 如果不是继续下一条规则
- 是否在比较
-
- 查看我们比较的项中是否有
boolean
- :white_check_mark: 如果有,那么将
boolean
转为number
并回到最初重新比较 :recycle: - :arrow_down: 如果不是继续下一条规则
- 查看我们比较的项中是否有
-
- 查看是否有一项是
object
- :white_check_mark: 如果有,那么将
object
转为其原始值primitive
并回到最初重新比较 :recycle: - :x: 如果还不是,只能返回
false
了:hankey:
- 查看是否有一项是
-
举几个:chestnut::
这么看来转换规则是不是很清晰明了:flushed:
附上一张转换规则图,忘记了就看看,当然正常情况下应该用 === 代替 == 避免不必要的麻烦:
ecma 的规范: http://www.ecma-international...
类型转换
上述在比较的过程中,涉及到类型的转换,如字符串转整数、布尔值转整数、以及获取对象原始值等等。了解一下这些不同类型之间是如何转换的:
获取对象原始值
接着我们再来研究一下对象怎么转换为原始值的:
我们需要知道转换类型的这个方法在 JS 源代码中是 ToPrimitive
这个方法,该方法有一个可选参数 PreferredType
,这个参数的作用是指定期望类型;如果第一个参数对应的对象可以被转换为不止一种类型,那么后者可以作为一种暗示,表示该对象应该转换为那种类型
-
- 默认情况下(期望类型默认为
number
)
-
- 调用
valueOf
方法:
- :white_check_mark: 如果返回的是原始值,那么就用这个
- :arrow_down: 如果返回的不是原始值,那么跳到下一步
- 调用
-
- 调用
toString
方法:
- :white_check_mark: 如果返回的是原始值,那么就用这个
- :x: 否则报错:hankey:
- 调用
- 默认情况下(期望类型默认为
-
- 如果期望类型为
string
:
-
- 调用
toString
方法:
- :white_check_mark: 如果返回的是原始值,那么就用这个
- :arrow_down: 如果返回的不是原始值,那么跳到下一步
- 调用
-
- 调用
valueOf
方法:
- :white_check_mark: 如果返回的是原始值,那么就用这个
- :x: 否则报错:hankey:
- 调用
- 如果期望类型为
-
- 如果对象是 Date 类型(期望类型为
string
):
-
- 调用
toString
方法:
- :white_check_mark: 如果返回的是原始值,那么就用这个
- :arrow_down: 如果返回的不是原始值,那么跳到下一步
- 调用
-
- 调用
valueOf
方法:
- :white_check_mark: 如果返回的是原始值,那么就用这个
- :x: 否则报错:hankey:
- 调用
- 如果对象是 Date 类型(期望类型为
简单的说就是默认调用 valueOf
方法,然后是 toString
方法;如果对象是 Date
类型或对象的期望类型为 string
,那么先调用 toString
方法:sleepy:
举几个:chestnut::chestnut::chestnut:吧:
普通的对象,首先调用 valueOf 方法,返回的结果并非原始值,那么会调用 toString 方法
假设我们重写 valueOf 方法,valueOf 和 toString 同时返回 string 原始值。使用 == 操作符可以看出,对象还是优先使用了 valueOf 方法返回的值
上面的数组同理,首先默认调用 valueOf 方法,如不是原始值,则调用 toString 方法
这个包括众多类型的项的数组也是一样:pig_nose:
再看看 Date 类型,他的期望类型是 string 因此首先调用的是 toString 方法,该方法返回一个原始值,那么就是用这个原始值
转换为 number
下面我们来看看转换成 number 类型的规则:
-
undefined
:point_right:NaN
如果是 undefined 则直接转换成 NaN -
null
:point_right:0
如果是 null 则转换成 0 -
boolean
:point_right:0/1
如果是 boolean 则转换成 0 或 1 -
string
:point_right:0/NaN/(parse to number)
如果是 string 则转换成对应的 number,空字符串转换为 0,无法转换的则为 NaN -
object
:point_right: 首先获取原始值然后再转为 number
看几个:chestnut::
转换为 string
转为 string 的规则为:
-
undefined
:point_right:'undefined'
-
null
:point_right:'null'
-
number
:point_right:'number
-
boolean
:point_right:'true'/'false'
-
object
:point_right: 首先获取原始值,然后转为 string
转为 boolean
常见的问题:哪些是 falsy 哪些是 truthy:
:x:下面这些在 JS 中都为 falsy 除此之外的都是 truthy
undefined null 0 "" NaN
因此转换规则如下:
-
undefined
:point_right:false
-
null
:point_right:false
-
number
:point_right: 当为 0 时false
否则为true
-
string
:point_right: 当为空字符串时为false
否则为true
-
object
:point_right:true
-
array
:point_right:true
-
Date
:point_right:true
:ramen:是几个例子:
附上一张不同类型间转换规则:
就写到这里,基本上 == 和类型转换就是这个样子:grey_exclamation:
EOF
参考:
以上所述就是小编给大家介绍的《???? 图解 == 操作符规则和不同类型间转换规则》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Android RxJava 操作符详解系列:条件 / 布尔操作符
- C语言中点操作符(.)和箭头操作符(->)的不同之处
- JavaScript骚操作之操作符
- JS操作符拾遗
- 浅谈JavaScript位操作符
- rxjs switchMap操作符
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。