首页 > 其他分享 >你真的理解==和===的区别吗?

你真的理解==和===的区别吗?

时间:2022-10-07 23:02:39浏览次数:49  
标签:返回 comparison false 区别 Type 理解 return 真的 true

用中文怎么叫合适? 相等?全等? 其实并不合适,叫double equals 或者treble equals,或者叫不懂的人觉得比较不专业的双等或者三等操作符,是更加严谨和正确的叫法。 为什么这么说?看完这篇博客你就明白了。 ####一、入门阶段:自我经验(一脚一坑) 我的理解是: ==是相等,值相等,返回true。 ===是全等,值相等,类型也相等,返回true。

上面的理解是错的,​​[]==false​​​和​​[1]===[1]​​​返回就可以推翻。​​[]==false​​,他们的值并不相等,但是返回true。[1]和[1],值相等,类型也相等,返回为false。因此上面理解是错的。

正确的理解是:

==是相等,先转换再比较,返回true。 ===是全等,不转换就比较,返回true。

​[]==false​​,false是转换为0,[]强制转换成0(解释不清楚),​​0 == 0​​​ ,返回为true。 ​​​[1] === [1]​​​,不转换就比较,​​[1]===[1]​​,左右的[1]指向内存中两个独立的,地址不同的数组,故返回false。

看下最简单的例子: ①基础类型vs基础类型 ​​1== true //true​​​ ​​​1 === true //false​​​ 再看两个复杂的例子: ②对象vs基础类型* ​​​[] == false //true​​​ ​​​[] === false //false​​​ ③对象vs对象 ​​​{age:6} == {age:6} //false​​​ ​​​{age:6} === {age:6} //false​​​ ​​​[1] == [1] //false​​​ ​​​[1] === [1] //false ​​ ####二、初级阶段:参考书籍(勉强避雷) 聪明的你会问了,​​[] == false​​​和​​false == []​​的结果一致吗? 答案是一致的,因为无论再操作符左侧还是右侧,它们都是操作数,位置是没有关系的。

为什么会出现上面的结果?

为什么 ​​1 == true​​​和​​[] == false​​返回true? 因为type coercion的存在,高设翻译为强制转型。 为什么会出现强制转换类型? 强制转换了谁的类型? 转换成了什么类型?

为什么​​{age:6} == {age:6}​​返回的是false? 他们看起来不是一样的吗,都是一个object,而且内部数据都是age:6,key-value值一模一样,为什么不返回true呢?

如果再在操作数中加入​​null​​​和​​undefined​​这两个神奇的类型呢? 问题就变的更复杂了...

来看下《Javascript高级程序设计》关于==和===的规则

1.如果有一个操作数是布尔值,则在比较前先将其转换为数值,true转换为1,false转换为0,例如false == 0,true == 1 2.如果一个操作数是字符串,另一个操作数是数值,先将字符串转换成数值,例如"1"==1,'' ==0 3.如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型按照前面的规则进行比较。(解释不清楚) 4.null和undefined是相等的。 5.如果有一个数是NaN,则相等操作符返回false,而不想等操作符返回true。NaN == NaN返回为false,因为规则如此。 6.如果两个操作数是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回true,否则返回false。 例如:var obj = {a:1};foo = obj;bar = obj;foo==bar;foo==bar返回为true,因为他们指向同一个对象,obj。

===和==的规则类似,唯一少了转换的一步。 第6步中的foo===bar返回true,如果不明白为什么?请看第三部分。

####三、高级阶段:参考规范(真正理解) 真的如高设所说的那样吗?其实不然。 下面是ecma-262的规范,其中有对==和===的执行定义,把解释不清楚干掉。 ​​www.ecma-international.org/publication…​7.2.13 Abstract Equality Comparison

The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed
as follows:
1. If Type(x) is the same as Type(y), then
a. Return the result of performing Strict Equality Comparison x === y.
2. If x is null and y is undefined, return true.
3. If x is undefined and y is null, return true.
4. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
5. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
8. If Type(x) is either String, Number, or Symbol and Type(y) is Object, return the result of the
comparison x == ToPrimitive(y).
9. If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of the
comparison ToPrimitive(x) == y.
10. Return false.

7.2.14 Strict Equality Comparison

The comparison x === y, where x and y are values, produces true or false. Such a comparison is performed
as follows:
1. If Type(x) is different from Type(y), return false.
2. If Type(x) is Number, then
a. If x is NaN, return false.
b. If y is NaN, return false.
c. If x is the same Number value as y, return true.
d. If x is +0 and y is ‑0, return true.
e. If x is ‑0 and y is +0, return true.
f. Return false.
3. Return SameValueNonNumber(x, y).
NOTE This algorithm differs from the SameValue Algorithm in

1.[]==false 来分析一个经典的例子:[]==false,看完彻底理解==的强制转换。 ①[]==false→**[]==0**

7.If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

你真的理解==和===的区别吗?_操作符

经过​​ToNumber(false)​​,false会被转换为0.

②[]==0→**''==0**

9.If Type(x) is Object and Type(y) is either String, Number, or Symbol, return the result of thecomparison ToPrimitive(x) == y

这个时候就比较复杂了...

你真的理解==和===的区别吗?_强制转换_02

你真的理解==和===的区别吗?_强制转换_03

按照规范,我们需要经过下面的一系列操作

→OrdinaryToPromitive([],default)
→OrdinaryToPromitive([],number)
→Get([],valueOf)
→Call(valueOf,[])
→Get([],toString)
→Call(toString,[])
→''

不要慌,用Javascript来描述,还是很简单的:

[].valueOf().toString()

③''==0→0==0

5. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.

2.[1]===[1] 再来看下===操作符,其中有句话可以完美解释[1]===[1]返回false,但是var obj = {a:1};foo = obj;bar = obj;foo===bar中foo===bar返回为true的原因。

3. Return SameValueNonNumber(x, y).

你真的理解==和===的区别吗?_操作符_04

由于[1]===[1]三等号左右的[1],不是same Object,因此返回为false.而foo===bar,三等号左右其实本质上都是指向obj这个对象,值相等更是必然,所以返回为true。

我们由此可以举一反三,[1]==true返回true,而[1,2,3]==true返回false的原因也不足为奇了。

  • 微信公众号: 大大大前端

标签:返回,comparison,false,区别,Type,理解,return,真的,true
From: https://blog.51cto.com/u_15725382/5735208

相关文章

  • 如何理解package.json中的proxy字段?
    入职新公司以来,第一个月接手vue项目,第二个月接手angularjs项目,第三个月加入react重构项目。心生感叹:业务驱动式学习是一种高效率的学习方式,保持好奇心,在业务中快速成长!新项......
  • PostCSS真的太好用了!
    在​​PostCSS官网​​有着这样的对PostCSS特性介绍,箭头后面是对应功能的插件及其github地址。increasecodereadability→​​Autoprefixer​​Usetomorrow'sCSS,toda......
  • 如何理解WeakMap?
    在学习​​缓存函数​​时,最后提到了WeakMap方式缓存(对入参类型为对象做缓存,并且当对象在WeakMap中的key没有引用时方便浏览器垃圾回收)Ifourparameterwereanobject(ra......
  • 深入理解JSON.stringify()
    就我目前4年(实习了1年,965了1年,996了2年,算3年感觉少了,说是4年老司机也不为过吧。)的工作经验来看,JSON.stringify一般有以下用途:深拷贝:深拷贝引用类型的数据序列化:服务端存储......
  • TCP与UDP的联系与区别
    TCP(TransmissionControlProtocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来......
  • TCP与UDP的区别和联系
     TCP与UDP的区别1.UDP支持一对一,一对多,多对一,多对多通信而TCP只能是一对一通信2.UDP不与对方建立连接,通信效果好实时通话,而TCP需要和对方建立连接。但是UDP虽然通信效......
  • 快速理解memset
    memset函数是在头文件:cstring 或 memory中 memset函数的作用是将数字以单个字节逐个拷贝的方式放到指定的内存中去memset(a,0,sizeofa);int类型的变量一般占......
  • TCP与UDP的联系与区别
    TCP(TransmissionControlProtocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来,其......
  • TCP与UDP的联系与区别
    一、联系这两个都是运输层协议;都是建立在ip之上的TCP叫做流式套接字,UDP是报文套接字。二、区别1、基于连接与无连接。2、TCP要求系统资源较多,UDP较少。3、UDP程序结构......
  • TCP与UDP区别与联系
    TCP与UDP区别总结:TCP面向连接,通过三次握手建立连接,四次挥手接除连接;UDP是无连接的,即发送数据之前不需要建立连接,这种方式为UDP带来了高效的传输效率,但也导致无法确保数......