从相等运算符的十步计算来看类型转换

JS 的隐式转换给我们带来了不少便利,然而在一些时候,过度的使用也会导致一些不可预料的问题,比如 1 + '1' 的结果,这是一类经常要注意的简单问题。隐式转换属于类型转换的一部分,类型转换是一个简单而又繁杂的话题。这篇文章旨在理清楚其中的一个相关操作 相等运算符

相等运算其中包括抽象相等(==)和严格相等(===),它们之间的区别仅在与,严格相等会直接比较类型,而不会做一些隐式转换。其实所谓的隐式转换,只是 EMCA 中规定的一些操作逻辑而已,今天,我们就深入其中,看看这层转换的外壳之下,究竟包含这什么。

相等运算符转换规则

比较 x == yxy 都是值,返回 true 或者 false。一个比较会执行如下步骤: 注: Type[x] 理解为 x 的类型。ToNumberToPrimitive 是类型转换中的一种处理,后面会提到。

  1. 如果 Type[x]Type[y] 的类型相同,那么执行严格相等比较。(所以说,可以理解为 ===== 的步骤之一)
  2. 如果 x 是 null 并且 y 是 undefined,那么返回 true。
  3. 如果 x 是 undefined 并且 y 是 undefined,那么返回 true。
  4. 如果 Type[x] 是 Number 并且 Type[y] 是 String,返回 x == !ToNumber(y) 的比较结果。
  5. 如果 Type[x] 是 String 并且 Type[y] 是 Number,返回 !ToNumber(x) == y 的比较结果。
  6. 如果 Type[x] 是 Boolean,返回 !ToNumber(x) == y 的比较结果。
  7. 如果 Type[y] 是 Boolean,返回 x == !ToNumber(y) 的比较结果。
  8. 如果 Type[x] 是 String,Number 或者 Symbol 并且 Type[y] 是 Object,返回 x == ToPrimitive[y] 的比较结果。
  9. 如果 Type[x] 是 Object并且 Type[y] 是 String,Number 或者 Symbol,返回 ToPrimitive[x] == y 的比较结果。
  10. 返回 false

化繁为简

上面的 10 条内容看起来头头是道,可是用来记忆就有诸多不便了。总结如下:

类型相同比较值,

nullundefined 总为 trueNumberString,ToNumber,

若有 Boolean 也 ToNumber。

Object 要 ToPrimitive,

其他结果返回 false复制代码

规则搞清楚以后,只需要弄明白 ToNumberToPrimitive 是什么就万事大吉了。我们先从简单的说起,

ToNumber 的规则,官方给出一个表格:

参数类型结果
Undefined返回 NaN
Null返回 +0
Boolean如果 argument 是 true,返回 1,否则返回 0
Number返回 argument 没有转换
String参考下面的转换算法
Symbol抛出类型错误
Object两步走:
1. 转换成基本值, ToPrimitive(argument, hint Number)
2. 返回 ToNumber()

好了,到此为止,似乎对 Obejct 的比较运算处理起来需要多一步先转换为数字(也只能这样),再跟具体 ToNumber 比较,由此我们可以进一步推测,在处理字符串,布尔值等基本数据类型的时候,应该会有 ToBoolean 或者 ToString 等等的内置工具(实际上类型转换的规则更多具体,ECMA 中有很详细的介绍)。这里要挖个坑,关于上图表格中的字符串转换算法,我有点看不懂 ECMA 中的介绍,需要继续研究。

关于 ToPrimitive 的内容也很简单,断言处理输入值,然后根据输入类型做不同处理得到基本值。

参考资料

  1. Abstract Equality Comparison

转载于:https://juejin.im/post/5ce27b9cf265da1bc64b94b1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值