JS中 [] == ![]结果为true,而 {} == !{}却为false, 追根刨底

转载自  JS中 [] == ![]结果为true,而 {} == !{}却为false, 追根刨底

console.log( [] == ![] )  // true
console.log( {} == !{} )  // false

在比较字符串、数值和布尔值的相等性时,问题还比较简单。但在涉及到对象的比较时,问题就变得复杂了。最早的ECMAScript中的相等和不相等操作符会在执行比较之前,先将对象转换成相似的类型。后来,有人提出了这种转换到底是否合理的质疑。最后,ECMAScript的解决方案就是提供两组操作符:

相等和不相等——先转换再比较      (==)

全等和不全等——仅比较而不转换  (===)

ECMAScript中相等操作符由两个等于号(==)表示,如果两个操作数相等,则返回true,这种操作符都会先转换操作数(通常称为强制转型),然后再比较它们的相等性

在转换不同的数据类型时,对于相等和不相等操作符:在JS高程中一书中给出如下的基本转换规则

①、如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false转换为0,而true转换为1;

②、如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值

③、如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较

这两个操作符在进行比较时则要遵循下列规则。

①、null 和undefined 是相等的

②、要比较相等性之前,不能将null 和 undefined 转换成其他任何值

③、如果有一个操作数是NaN,则相等操作符返回 false ,而不相等操作符返回 true。重要提示:即使两个操作数都是NaN,相等操作符也返回 false了;因为按照规则, NaN 不等于 NaN

④、如果两个操作数都是对象,则比较它们是不是同一个对象,如果两个操作数都指向同一个对象,则相等操作符返回 true;否则, 返回false

这里说一下题外话:[] 和 {} 都是属于引用类型,引用类型是存放在堆内存中的,而在栈内存中会有一个或者多个地址来指向这个堆内存相对应的数据。所以在使用 == 操作符的时候,对于引用类型的数据,比较的是地址,而不是真实的值。

现在来探讨 [] == ! [] 的结果为什么会是true
①、根据运算符优先级 ,! 的优先级是大于 == 的,所以先会执行 ![]

!可将变量转换成boolean类型,null、undefined、NaN以及空字符串('')取反都为true,其余都为false。

所以 ! [] 运算后的结果就是 false

也就是 [] == ! [] 相当于 [] == false

②、根据上面提到的规则(如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false转换为0,而true转换为1),则需要把 false 转成 0

也就是 [] == ! [] 相当于 [] == false 相当于 [] == 0

③、根据上面提到的规则(如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较,如果对象没有valueOf()方法,则调用 toString())

而对于空数组,[].toString() ->  '' (返回的是空字符串)

也就是  [] == 0 相当于 '' == 0

④、根据上面提到的规则(如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值)

Number('') -> 返回的是 0

相当于 0 == 0 自然就返回 true了

总结一下:

[] == ! []   ->   [] == false  ->  [] == 0  ->   '' == 0   ->  0 == 0   ->  true

 

那么对于 {} == !{} 也是同理的

关键在于  {}.toString() ->  NaN(返回的是NaN)

根据上面的规则(如果有一个操作数是NaN,则相等操作符返回 false)

总结一下:

{} == ! {}   ->   {} == false  ->  {} == 0  ->   NaN == 0    ->  false
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/323608.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P2261-[CQOI2007]余数求和【数论,约数】

正题 评测记录:https://www.luogu.org/recordnew/lists?uid52918&pidP2261 题目大意 求∑i1nk%i\sum^{n}_{i1}k\%i∑i1n​k%i。 解题思路 将k%ik\%ik%i展开一下,k−i∗⌊k/i⌋k-i*\lfloor k/i\rfloork−i∗⌊k/i⌋,然后答案就是 ∑i1nk−i∗⌊k/…

Centos7 amp;amp; Docker amp;amp; Jenkins amp;amp; ASP.NET Core

写在前面 Docker一直很火热,一直想把原本的Jenkins自动部署工具搬到Docker上面,无奈今年一直忙于各种事情,迟迟未实施这个事情,正好迎来了dotnet core 2.0 的正式发布,升级项目的同时,顺便直接将Jenkins搬到…

国民体质测定标准手册及标准解析成JSON文件计算分数,java解析excel文件

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂 前言 现在是:2022年6月14日10:07:27 最近在做体质测评的功能,需要依据《国民体质测定标准手册及标准》,根据用户的个人信息,从而计算出各个…

getchar与putchar用法

#include<stdio.h>main(){int i;igetchar();//相当于char i;scanf("%c",&i); putchar(i);//相当于printf("%c",i); 需要i是字符才能输出不能是变量printf("\n");printf("%d",i);}输出结果一致 #include<stdio.h>main…

TCP为什么是三次握手和四次挥手

转载自 TCP为什么是三次握手和四次挥手 为什么建立连接是三次握手断开连接是四次挥手&#xff1f; 三次握手的流程和四次挥手的流程是什么&#xff1f; 三次握手与四次回收分别对应TCP连接与断开过程 tcp报文格式 标志位含义 ACK&#xff1a;确认序号有效。 SYN&#x…

P1072-Hankson的趣味题【数论,gcd】

正题 评测记录:https://www.luogu.org/recordnew/lists?uid52918&pidP1072 题目大意 a1gcd(a0,x)a1gcd(a0,x)b1gcd(b0,x)b1gcd(b0,x)求xx解题思路如果 a1=gcd(a0,x)" role="presentation">a1=gcd(a0,x)a1=gcd(a0,x) 所以xka∗a1xka∗a1b1gcd(b0,x)b1g…

HTM文件中使用vue

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。 代码啊&#xff0c;尤其是比较重要客户的项目&#xff0c;即使包出去了&#xff0c;代码也一定要回到自己手里&#xff0c;不然干着急。 这个项目&#xff0c;已经经过两手了&#xff0c…

LVS三种模式的区别及负载均衡算法

转载自 LVS三种模式的区别及负载均衡算法 LVS简介 LVS&#xff08;Linux Virtual Server&#xff09;即Linux虚拟服务器&#xff0c;是一个虚拟的服务器集群系统&#xff0c;由章文嵩博士在1998年5月成立&#xff0c;在linux2.6后将lvs自动加入了kernel模块&#xff0c;我们…

POJ3696-The Luckiest number【数论,欧拉定理】

正题 题目链接:http://poj.org/problem?id3696 题目大意 求多少个8连在一起是LL的倍数。解题思路将x个8连在一起分解一下 10x&#x2212;19" role="presentation">10x−1910x−19 那么就是 L|2∗(10x−1)9L|2∗(10x−1)9dgcd(L,8)dgcd(L,8)分解一下 9…

王者荣耀是怎样炼成的(一)《王者荣耀》用什么开发,游戏入门,unity3D介绍

在国内&#xff0c;如果你没有听说过《王者荣耀》&#xff0c;那你一定是古董级的人物了。 《王者荣耀》&#xff08;以下简称“农药”&#xff09;&#xff0c;专注于移动端&#xff08;Android、IOS&#xff09;的MOBA游戏。笔者看到这么火爆&#xff0c;就萌生了了解一下这类…

Java数组,字符串

数组定义 数据类型 名称[] new 数据类型[n] int data[] new int[3];data[0] 10;data[1] 11;data[2] 25;一步定义数组&#xff0c;并循环输出 int data[] new int[] {1,2,3,4};for (int i : data) {System.out.println(i);}字符串数组定义&#xff0c;并循环 String d…

新工作感悟~辞旧迎新~

“大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂”现在是&#xff1a;2022年6月21日22:33:34公众号又好久没有更新啦。从以前的日更&#xff0c;到后来的周更&#xff0c;再到后来的月更……不知道会不会到不更的结局。。。最近换工作了&…

POJ1845-Sumdiv【逆元,等比数列,约数】

正题 题目链接:http://poj.org/problem?id1845 题目大意 求ABAB次方的约数和。答案mod 9901mod9901解题思路 AA的约数和就是 (1+p1+p12+p13...+p1c1)+(1+p2+p22+p23...+p2c2)+...(1+pn+pn2+pn3...+pncn)" role="presentation">(1+p1+p21+p31...+pc11)+(…

关于Spring底层原理面试的那些问题,你是不是真的懂Spring?

转载自 关于Spring底层原理面试的那些问题&#xff0c;你是不是真的懂Spring&#xff1f; 1.什么是 Spring 框架&#xff1f;Spring 框架有哪些主要模块&#xff1f; Spring 框架是一个为 Java 应用程序的开发提供了综合、广泛的基础性支持的 Java 平台。Spring帮助开发者解…

ASP.NET Core Web服务器 Kestrel和Http.sys 特性详解

1.1. 名词解释 内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。 用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。 1.2. Kestrel基本工作原理 Kestrel是…

糊涂工具类(hutool)post请求设置body参数为json数据

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号雄雄的小课堂 今天介绍一个案例&#xff0c;糊涂工具类&#xff08;hutool&#xff09;post请求设置body参数为json数据&#xff0c;刚开始写的总是报错&#xff0c;下面是正确的代码&#xff1a; /*** 添加动作* pa…

Failed to execute

今天用dev c无论打编译什么都是出现如下结果&#xff1a; 后来终于找到解决办法了: 原来是这里出现问题了&#xff0c;我的电脑是32位的&#xff0c;必须也是32位的编译系统。否则不管输入什么都是上面的结果&#xff1b; 所以以后不管下载软件还是编译东西第一步一定要看自…

P1313-计算系数【组合数,二项式定理】

正题 评测链接:https://www.luogu.org/recordnew/lists?uid52918&pidP1313 题目大意 求(axby)k(axby)k&#xff0c;求多项式展开后xnymxnym项的系数&#xff0c;答案mod 10007mod10007。 解题思路 二项式定理 (axby)k∑i0kCikaibk−ixiyi(axby)k∑i0kCkiaibk−ixiyix…

web.xml 组件加载顺序

转载自 web.xml 组件加载顺序 在配置项目组件的过程中&#xff0c; 了解Tomcat加载组件顺序很有必要。 例如某些框架如Quartz的集群功能需要数据库的支持&#xff0c; 数据库的加载肯定要在框架组件加载之前。 经过查阅和Debug发现&#xff0c; web.xml组件加载顺序为&#…

日期工具类处理总结(全)

文章目录前言代码展示前言 最近项目中用到了一些关于日期类和字符串类的处理&#xff0c;用到一次就得去写一次&#xff0c;后来想了想这样不光效率低还浪费时间浪费精力&#xff0c;于是就将常用的一些方法提取成工具类&#xff0c;每个项目都考进去一次&#xff0c;用的时候…