为什么 [] == ![] 为 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

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

相关推荐
小小小小宇1 分钟前
前端双Token机制无感刷新
前端
小小小小宇3 分钟前
重提React闭包陷阱
前端
小小小小宇19 分钟前
前端XSS和CSRF以及CSP
前端
UFIT23 分钟前
NoSQL之redis哨兵
java·前端·算法
超级土豆粉30 分钟前
CSS3 的特性
前端·css·css3
星辰引路-Lefan30 分钟前
深入理解React Hooks的原理与实践
前端·javascript·react.js
wyn2000112842 分钟前
JavaWeb的一些基础技术
前端
江城开朗的豌豆1 小时前
JavaScript篇:函数间的悄悄话:callee和caller的那些事儿
javascript·面试
Hygge-star1 小时前
Flask音频处理:构建高效的Web音频应用指南
前端·flask·音视频·pygame·csdn开发云
江城开朗的豌豆1 小时前
JavaScript篇:回调地狱退散!6年老前端教你写出优雅异步代码
前端·javascript·面试