【快速理解】js中相等操作运算规律

背景:js中的相等比较运算规则十分繁杂。本文以流程的角度去解释非严格全等的行为,尝试帮助我们快速理清js中比较运算的规律。同时还有+0和-0的比较、NaN和NaN的比较。为啥0 == null为false。

js中的相等比较方式

首先,了解一下JavaScript中存在的等值比较操作有哪些【1】:

  1. 抽象相等比较 (“loose equality”,“double equals”) ,使用 x == y。

    噩梦开始的地方,可以判断为true的边界很大,不同类型的相等比较,也可以在相等的范围里。

  2. 严格相等比较 (也被称作全等比较,“strict equality”, “identity”, “triple equals”),使用 x === y。

    增加判断的准确性:收窄了js中可以判断为true的边界,简化判断流程。把不同类型却能判为相等的情况,划到不相等的范围。

  3. 以及 Object.is (ECMAScript 2015/ ES6 新特性),使用 Object.is(x, y)。

    增加判断的灵活性:严格相等比较中:+0 === -0是相等的,NaN === NaN是不相等的,Object.is就可以给这两种情况给出相反的结果,其它跟严格相等规则一样。

当js中出现x == y,es规范中的处理流程

步骤一,先依次判断:

  • 1.1 先判断x,然后是y,如果有一个不是正常值(比如抛出一个错误),立即中断执行,结束。否则进入1.2。

  • 1.2 如果x和y类型相同,执行严格相等运算x === y,并作为结果返回,结束。否则进入步骤二。

    如果是两个对象,比较的是他们对应的对象所在内存的位置

步骤二,此时x和y类型不同,会根据表格中的搭配,按步骤依次往下匹配(x和y在==的前后位置不要求):

步骤xy转换结果下一步
2.1nullundefinedtrue结束
2.2数值字符串把字符串转为数值ToNumber(字符串) == 数值重新比较结果里的表达式
2.3布尔值其它类型把布尔值转为数值ToNumber(布尔值) == 其它类型重新比较结果里的表达式
2.4对象字符串、数值、Symbol值ToPrimitive(对象)ToPrimitive(对象)== y重新比较结果里的表达式
2.5任意值任意值false结束

表格中:

  • 如果出现了转换,则要回到步骤一,重新比较结果列里的表达式,直到结束。
  • ToNumber(参数)表示把参数转为数值。
  • ToPrimitive(对象)通过尝试调用 对象 的对象.toString()对象.valueOf() 方法,将该对象 转换为原始值(Primitive)。

快速记忆【1,2】:

  • 在es规范里,undefind和null只有等于互相时,是true,和其它类型比较都是false。也就是说0 == null结果为false是es规范导致的。更多细节参考mdn
  • 转换只会进行(字符串、布尔值)转为数值;(对象)转为原始值两种情况。

上例子

// == 例子
0 == null // false
// 在步骤二中只匹配到2.5,返回false,结束
// 也就是说在es规范里,undefind和null只有等于互相时,是true,和其它类型比较都是false。但特殊情况下,浏览器可能存在null == 对象为ture的情况,具体参阅mdn

false == '' // true
// 在表格里最先匹配到了2.3,会把false转为0,变成0 == ''
// 然后0 == '' 在表格里最先匹配到了2.2,把''转为0,变成0 == 0
// 最后,0 == 0会回到1.2中进行全等比较,并得出最终结果,结束比较

[3,4] == '3,4' // true
// 首先在表格里匹配到了2.4,经过[3,4].toString()转换为'3,4',变成'3,4' == '3,4'
// 最后'3,4' == '3,4'回到1.2进行全等比较

总结来源
【1】 MDN
非严格相等 == 最终的比较方式等同于全等操作符 === 的比较方式。相等操作符满足交换律。

【2】 读懂es6规范

  1. ReturnIfAbrupt(x).
  2. ReturnIfAbrupt(y).
  3. If Type(x) is the same as Type(y), thenReturn the result of performing Strict Equality Comparison x === y.
  4. If x is null and y is undefined, return true.
  5. If x is undefined and y is null, return true.
  6. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
  7. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
  8. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
  9. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
  10. If Type(x) is either String, Number, or Symbol and Type(y) is Object, then return the result of the comparison x == ToPrimitive(y).
  11. If Type(x) is Object and Type(y) is either String, Number, or Symbol, then return the result of the comparison ToPrimitive(x) == y.
  12. Return false.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值