为什么 [] == ![] 为 true?

🧑‍💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣

前言

xml 复制代码
面试官问我,[] == ![] 的结果是啥,我:蒙一个true; 面试官:你是对的;我:内心非常高兴;
面试官:解释一下为什么; 我:一定要冷静,要不就说不会吧;这个时候,面试官笑了,同学,感觉你很慌的一批啊!

不必慌张,我们慢慢来!

在当今的编程领域,面试不仅是技术能力的考察,更是思维灵活性与深度理解的试金石。面试中偶遇诸如 [] == ![] 表达式这类题目,虽让人初感意外,实则深藏玄机,考验着我们对于JavaScript这类动态语言特性的透彻理解。这类问题触及了类型转换、逻辑运算以及语言设计的微妙之处,促使我们跳出日常编码的舒适区,深入探索编程语言的底层机制。接下来,我们将一步步揭开这道题目的神秘面纱,不仅为解答此类问题提供思路,更旨在通过这一过程,提升我们对JavaScript核心概念的掌握与应用能力。

首先我们来聊一下基础的东西。

1.原始值转布尔

首先是原始值转布尔

xml 复制代码
console.log(Boolean(1));//true
console.log(Boolean(0));//false
console.log(Boolean(-1));//true
console.log(Boolean(NaN));//false
console.log(Boolean('abc'));//true
console.log(Boolean(''));//false
console.log(Boolean(false));//flase
console.log(Boolean(undefined));//false
console.log(Boolean(null));//false

2.原始值转数字

xml 复制代码
console.log(String(123));//'123'
console.log(String(true));//'true'
console.log(String(false));//'false'
console.log(String(undefined));//'undefined'
console.log(String(null));//'null'

3.原始值转字符串

xml 复制代码
console.log(String(123));//'123'
console.log(String(true));//'true'
console.log(String(false));//'false'
console.log(String(undefined));//'undefined'
console.log(String(null));//'null'

然后我们来了解一下与对象有关的转换逻辑

4. 原始值转对象

xml 复制代码
let a = new Number(1)
console.log(a);//[Number: 1]

其实也没有很特殊的,就是利用构造函数去进行显式转换即可。

5.对象转原始值

5.1 对象转布尔

首先我们来到这题,最后结果会被打印,说明对象在转换为布尔值的时候,不管什么对象,都是被转换为true。

5.2 + 一元运算符

我们先来了解一下,一元运算符的作用。查阅js官方文档,我们可以知道就是调用ToNumber()得到结果。而ToNumber()就是调用Number方式所调用的内置函数,因此就是强制转换为数字。我们也可以理解为+和Number()的作用是一样的。

5.3 + 二元运算符

二元运算符调用ToPrimitive()方法(ToNumber中的,转换方式有差异)。

5.4 ToNumber()方法

那么这个方法具体执行过程是什么呢?我们可以看到,如果是基本数据类型转数字,我们之前已经聊到,因此不必多聊,而面对对象转数字的时候,我们会先调用ToPrimitive方法。

5.5 ToPrimitive()方法

关于这个方法,我们要看是被ToNumber还是Totring方法给调用了。二者在返回值的顺序上会有所差异。 我们来聊一聊里面的valueOf()和toString()方法。

5.6 toString()和valueOf()方法

xml 复制代码
1. {}.toString() 得到由"[object class ] "组成字符串
2. [].toString() 返回由数组内部元素以逗号拼接的字符串
3. xx.toString() 返回字符串字面量

- valueOf 也可以将对象转成原始类型
1. 包装类对象


5.6 == 比较

我们首先引入官方文档

首先我们看二者类型相同时的比较, 里面有一点需要注意,只要有一个NaN就返回false,其他的我们应该都清楚。

二者类型不相等时,我们需要特别注意的是,null和undefined是相等的,字符串和数字则把字符串转数字,布尔和其他把布尔转数字,出现对象先把对象转原始值。

估计上面的大量干货已经把大家快搞懵逼了,此这里我们做个简单小结,这里面的方法前面都有提到哦。

5.7 小结(重点)

对象转数字

Number(obj) => ToNumber(obj) => ToNumber(ToPrimitive(obj,Number))

对象转字符串

String(obj) => ToString(obj) => ToString(ToPrimitive(obj,String))

5.8 大量实战练习

这一题我们知道+的作用和Number的方法是一样的。因此是转换为数字123.

那么这一题,我们考虑到

Number([]) => ToNumber([]) => ToNumber(ToPrimitive([], Number))=> ToNumber('') => 0

这里只要对象转布尔均为true

这里的底层原理(5.3里说了)是,我们首先两边都调用ToPrimitive方法,看看有没有字符串,有的话就把另一方转换为字符串,没有的话就全部调用ToNumber方法相加。

这里也是一样的原理。

我们先把两边转换为原始值,左边为' ',右边为'[object object]',发现存在字符串,因此相加。

这里只要我们看5.6就可以很轻松搞懂。

同上一个。

首先有对象,我们把对象转原始值,然后为NaN,为false.

最后回到我们最开始的题目,首先碰见![],我们先把[]转为布尔,为true,!true为false,然后把左边对象转原始值,为' ' == false,出现布尔和字符串,把布尔转数字,为' ' == 0,出现字符串和数字,把字符串转数字,为0 == 0,因此最后结果为true

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

相关推荐
然我7 分钟前
不用 Redux 也能全局状态管理?看我用 useReducer+Context 搞个 Todo 应用
前端·javascript·react.js
前端小巷子12 分钟前
Web 实时通信:从短轮询到 WebSocket
前端·javascript·面试
神仙别闹15 分钟前
基于C#+SQL Server实现(Web)学生选课管理系统
前端·数据库·c#
web前端神器22 分钟前
指定阿里镜像原理
前端
枷锁—sha26 分钟前
【DVWA系列】——CSRF——Medium详细教程
android·服务器·前端·web安全·网络安全·csrf
枷锁—sha28 分钟前
跨站请求伪造漏洞(CSRF)详解
运维·服务器·前端·web安全·网络安全·csrf
群联云防护小杜44 分钟前
深度隐匿源IP:高防+群联AI云防护防绕过实战
运维·服务器·前端·网络·人工智能·网络协议·tcp/ip
DanB241 小时前
html复习
javascript·microsoft·html
汉得数字平台1 小时前
【鲲苍提效】全面洞察用户体验,助力打造高性能前端应用
前端·前端监控
花海如潮淹1 小时前
前端性能追踪工具:用户体验的毫秒战争
前端·笔记·ux