美文网首页
js中的【相等】

js中的【相等】

作者: 任无名F | 来源:发表于2017-05-03 23:53 被阅读0次

先看一道坑爹的题目:

if([]) console.log(1);
if({}) console.log(2);
if([] == false) console.log(3);
if({} == false) console.log(4);
if([1] == [1]) console.log(5);

问:最终的结果是什么?

众所周知,js中==与===是有很大区别的,主要在于==会先尝试将两边的变量转化为同一类型再进行比较,这就导致使用==的时候,即使两边的东西从外观上看风马牛不相及,最后也可能得到true的结果,以上的题目便是几个例子。

但实际上,js相等运算符的比较结果还是有迹可循的,参考了网上的资料,总结如下:

抽象相等

考虑 x == y 的结果时
一、 Type(x)与Type(y)相同:

  1. Type(x)为undefined或null,结果为true
  2. Type(x)为Number,则比较数字的值,有几个特殊情况:当x、y至少一个为NaN时,结果为false;-0 == +0结果为true
  3. Type(x)为String,与常识一致
  4. Type(x)为Boolean,与常识一致
  5. Type(x)为Object,必须相同引用才会得到true,即[1] == [1]结果为false

二、 Type(x)与Type(y)不同:

  1. undefined == null,结果为true
  2. String与Number比较,将String转换为Number后比较,例:1 == "1",结果为true
  3. Boolean与Number比较,将Boolean转换为Number后比较,例:true == 1,false == 0,结果均为true
  4. Object与String或Number比较,将Object转换为String,再使用对应的规则继续进行转换,例:["1"] == 1,先将["1"]转换为"1",再将"1"转换为1,最后结果为true
  5. 其他结果为false
    (这部分的更正在下方!)

严格相等

考虑 x === y 的结果时
一、 Type(x)与Type(y)不同:结果为false,这回干脆多了

二、 Type(x)与Type(y)相同:

  1. Type(x)为undefined或null,结果为true
  2. Type(x)为Number,则比较数字的值,有几个特殊情况:当x、y至少一个为NaN时,结果为false;-0 == +0结果为true
  3. Type(x)为String,与常识一致
  4. Type(x)为Boolean,与常识一致
  5. Type(x)为Object,必须相同引用才会得到true,即[1] == [1]结果为false

总结

当Type(x)与Type(y)相同时,抽象相等与严格相等是没有什么区别的;当Type(x)与Type(y)不同时,严格相等的结果一律为false,但是抽象相等会有很多种情况,也是最容易出错的地方。


经过再次的学习,我认识到关于抽象相等 ,其实是可以抛弃之前繁琐的规则的,并且之前的说法有些谬误,技巧如下图:

一张图总结 == 运算符
  1. 首先,undefined 与 null 互相相等,但与其他类型均不等(就是图右半部分)
  2. Boolean 与 String 之间比较,先转化成Number,再进行 === 比较
  3. Boolean/String与Number比较,也是先转化成Number,再进行 === 比较(以上两条为图左半部分的下半部分,N意为Number强制转换)
  4. Object与Boolean、String、Number类型比较,需要先进行toPremitive(obj),得到的结果,再进行 == 比较。

ToPrimitive(A)通过尝试依次调用 A 的A.toString() 和 A.valueOf() 方法,将参数 A 转换为原始值(Primitive)。

上面是MDN关于ToPrimitive的原文,但是太简略了,实际情况比这个要复杂一点
经过我自己的测试,首先 ToPrimitive(A) 是会先调用 A.valueOf() 的,但是只有在 A.valueOf() 得到的是原始值时,才会使用;如果 A.valueOf() 结果仍然是一个对象,就会再去调用 A.toString()

重点就是第四条!我们带着第四条来解析题目!
if([] == false) console.log(3); 
// 调用toPremitive([]),先看 [].valueOf() 的结果,发现结果仍然是 [],不是原始值!
// 继续调用[].toString(),这时结果是 "",终于是原始值了
// 然后比较 false == "",此时应用第三条,两边都转化成0,结果是 true

if({} == false) console.log(4); 
// 和上一个类似,调用toPremitive({}),先看 {}.valueOf() 的结果,发现结果仍然是 {},不是原始值!
// 继续调用{}.toString(),这时结果是 "[object Object]",终于是原始值了
// 然后比较 false == "[object Object]",应用第三条,左边转化成0,右边转化成NaN,结果是 false

其他题目解析

if([]) console.log(1); // 1,引用类型的内存地址不为空,所以都是true
if({}) console.log(2); // 2,引用类型的内存地址不为空,所以都是true
if([1] == [1]) console.log(5); // 无打印,两个Object不是指向同一个引用,结果为false

相关文章

  • js中的【相等】

    先看一道坑爹的题目: 问:最终的结果是什么? 众所周知,js中==与===是有很大区别的,主要在于==会先尝试将两...

  • JS 中的相等

    SameValueNonNumber 计算非数字类型x,y是否相同 规则: x 不是 Number 类型。 x 和...

  • JS杂记

    1、Undefined 与 Null 的区别 Undefined 与 null 的值相等,但类型不相等。在js中,...

  • 关于js中的双等号问题

    js中存在==和===两种校验是否相等的运算符。 ==代表值相等 ===代表值和类型都相等 由于双等号的存在,使用...

  • 逻辑运算符、赋值运算符、关系运算符、相等运算符、条件运算符

    JS中为我们提供了三种逻辑运算符 赋值运算符 关系运算符 相等运算符 相等运算符用来比较两个值是否相等,如果相等会...

  • js中的相等运算符

    刚才看犀牛书,看到这个知识点,记录一下: 严格相等运算符“===” 相等运算符“==” 相等运算符和严格相等运算符...

  • []==[]为false,[]==![]为true

    JS真是博大精深啊,看似相等,其实不等,而看似不等,却是相等。 没错,你没有看错,JS就是这么不可思议! 这个问题...

  • 2019-06-10

    js基础知识 相等运算符: 相等运算符用来比较两个值是否相等,如果相等会返回True,否则返回flase 使用 =...

  • js世界中的四种相等

    js中有四种元语相等,分别为==,===, sameValue, sameValueZero,下面分别介绍一下其异...

  • 前端(运算符)

    与或运算 Unicode编码 相等运算符 条件运算符 js操作属性 js函数

网友评论

      本文标题:js中的【相等】

      本文链接:https://www.haomeiwen.com/subject/iloltxtx.html