面试官:[]==![]为什么返回true?

9959次阅读 306人点赞 作者: WuBin 发布时间: 2024-01-10 17:21:09
扫码到手机查看

转换规则

我总结了以下==的隐式转换规则,一些简单的就忽略掉了:

类型相同的比较:

(1)如果类型是 Undefined 或 Null,返回true

null == null; // true

如果一个是 +0,另一个是 -0,返回true

+0 == -0; // true

(3)如果类型是对象,二者引用同一个对象,返回true,反之返回false

{} == {}; // false

null 和 undefined 比较: 仅当它们之间的比较时,返回 true。

null == undefined; // true

NaN 比较: NaN 与任何值比较都返回 false,包括NaN自己。

NaN == NaN;   // false

字符串与数字比较: 如果其中一个操作数是字符串,另一个是数字,将字符串转换为数字,然后进行比较。

'5' == 5;   // true,将字符串 '5' 转换为数字 5 进行比较

布尔值与非布尔值比较: 布尔值无法直接比较,需先将布尔值转换为数字(true 转换为 1,false 转换为 0),非布尔值也需要转换成数字再比较。

true == 1;  // true,将布尔值 true 转换为数字 1 进行比较
false == '123'; // false,将布尔值 false 转换为数字 0 ,将字符串 '123' 转换为数字 123 进行比较

对象与原始类型比较:

如果其中一个是对象,另一个是原始类型,将对象通过ToPrimitive转换为原始类型,然后进行比较。(即如果原始类型为字符串,则对象转换成字符串再比较;如果原始类为布尔值,则将布尔值与对象都转换成数字进行比较;如果原始类为数字,则将对象转换成数字进行比较。)

{} == 1;  //false

ToPrimitive这篇文章中详细介绍过,这里我们直接当做公式套用。

ToPrimitive(obj, Number) ==> Number({})

  1. 如果 obj 是基本类型,直接返回
  2. 否则,调用 valueOf 方法,如果得到原始值,则返回
  3. 否则,调用 toString 方法,如果得到原始值,则返回
  4. 否则,报错

首先{}先被ToPrimitive转换成字符串"[object Object]",就相当于直接判断"[object Object]" == 1,字符串与数字的比较中,又要将字符串转换成数字,"[object Object]"转换成数字为NaN,而NaN与任何值比较都为false

所以{} == 1返回false

关系转换图如下:

回到[] == ! []

这里判断[]![],两边都是对象,那怎么比呢,我们发现右边还有一个!,我们知道!的优先级是要大于==的,那么先进行非运算。

关于!

关于!,文档这样描述:Annotated ES5 11.4.9
简而言之,!这个运算符会进行两步操作:
  1. !后面的操作数转换成布尔值

  2. 将这个布尔值取反

于是我们判断![],将[]转换成布尔值,我们在官方文档中就知道了,任何对象转换成布尔值都得到ture,然后在取反,得到![]false
所以最终判断的流程为:

原式[] == ![]经过!运算将等式右边转换成了false。即[] == false

接着,根据==隐式转换规则,等式两边为对象和布尔,那么它们都应该转换成数字进行比较。

[]经过ToPrimitive会被转换成字符串""。再将等号两边的字符串""和布尔值false转换成数字0,得到0 == 0。打印得到true

所以实际在进行[] == ! []判断时,在JS引擎内部,会将这行代码执行成这个样子:

[] == ![]

[] == !true // 将空数组这个对象类型转换成布尔值

[] == false // ! 运算符对 true 进行取反

'' == false // 对 [] 进行 ToPrimitive 操作,返回一个空对象 

0 == 0 // 将等号两边都转换成数字类型

相关资料

点赞 支持一下 觉得不错?客官您就稍微鼓励一下吧!
关键词:==
推荐阅读
  • uniapp实现被浏览器唤起的功能

    当用户打开h5链接时候,点击打开app若用户在已经安装过app的情况下直接打开app,若未安装过跳到应用市场下载安装这个功能在实现上主要分为两种场景,从普通浏览器唤醒以及从微信唤醒。

    8769次阅读 563人点赞 发布时间: 2022-12-14 16:34:53 立即查看
  • Vue

    盘点Vue2和Vue3的10种组件通信方式

    Vue中组件通信方式有很多,其中Vue2和Vue3实现起来也会有很多差异;本文将通过选项式API组合式API以及setup三种不同实现方式全面介绍Vue2和Vue3的组件通信方式。

    3674次阅读 274人点赞 发布时间: 2022-08-19 09:40:16 立即查看
  • JS

    几个高级前端常用的API

    推荐4个前端开发中常用的高端API,分别是MutationObserver、IntersectionObserver、getComputedstyle、getBoundingClientRect、requ...

    13775次阅读 888人点赞 发布时间: 2021-11-11 09:39:54 立即查看
  • PHP

    【正则】一些常用的正则表达式总结

    在日常开发中,正则表达式是非常有用的,正则表达式在每个语言中都是可以使用的,他就跟JSON一样,是通用的。了解一些常用的正则表达式,能大大提高你的工作效率。

    12532次阅读 422人点赞 发布时间: 2021-10-09 15:58:58 立即查看
  • 【中文】免费可商用字体下载与考证

    65款免费、可商用、无任何限制中文字体打包下载,这些字体都是经过长期验证,经得住市场考验的,让您规避被无良厂商起诉的风险。

    11038次阅读 881人点赞 发布时间: 2021-07-05 15:28:45 立即查看
  • Vue

    Vue3开发一个v-loading的自定义指令

    在vue3中实现一个自定义的指令,有助于我们简化开发,简化复用,通过一个指令的调用即可实现一些可高度复用的交互。

    15139次阅读 1207人点赞 发布时间: 2021-07-02 15:58:35 立即查看
  • JS

    关于手机上滚动穿透问题的解决

    当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。在PC上使用css即可解决,但是在手机端,情况就变的比较复杂,就需要禁止触摸事件才可以。

    14612次阅读 1191人点赞 发布时间: 2021-05-31 09:25:50 立即查看
  • Vue

    Vue+html2canvas截图空白的问题

    在使用vue做信网单页专题时,有海报生成的功能,这里推荐2个插件:一个是html2canvas,构造好DOM然后转canvas进行截图;另外使用vue-canvas-poster(这个截止到2021年3月...

    28356次阅读 2230人点赞 发布时间: 2021-03-02 09:04:51 立即查看
  • Vue

    vue-router4过度动画无效解决方案

    在初次使用vue3+vue-router4时候,先后遇到了过度动画transition进入和退出分别无效的情况,搜遍百度没没找到合适解决方法,包括vue-route4有一些API都进行了变化,以前的一些操...

    24476次阅读 1885人点赞 发布时间: 2021-02-23 13:37:20 立即查看
交流 收藏 目录