面试官问我为什么 [] == ![] 为 true, 我表面冷静,实则内心慌的一批

前言

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

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

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

1.原始值转布尔

首先是原始值转布尔

javascript 复制代码
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.原始值转数字

javascript 复制代码
console.log(Number('123'));//123
console.log(Number('hello'));//NaN
console.log(Number(true));//1
console.log(Number(false));//0
console.log(Number(''));//0
console.log(Number(' '));//0
console.log(Number(undefined));//NaN
console.log(Number(null));//0

3.原始值转字符串

javascript 复制代码
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. 原始值转对象

javascript 复制代码
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()方法

vbscript 复制代码
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

相关推荐
落霞的思绪25 分钟前
CSS复习
前端·css
咖啡の猫2 小时前
Shell脚本-for循环应用案例
前端·chrome
uzong4 小时前
面试官:Redis中的 16 库同时发送命令,服务端是串行执行还是并行执行
后端·面试·架构
关键帧-Keyframe5 小时前
音视频面试题集锦第 26 期
面试·音视频
百万蹄蹄向前冲5 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5815 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路5 小时前
GeoTools 读取影像元数据
前端
ssshooter6 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
你的人类朋友6 小时前
【Node.js】什么是Node.js
javascript·后端·node.js
Jerry7 小时前
Jetpack Compose 中的状态
前端