面试题:为什么[ ] == [ ] 为false, [ ] == ![ ] 为true?

前言

这两个表达式涉及到 JS 中类型转换和比较操作符的行为。JS 是一种灵活的动态语言,它有一套自己的类型转换规则,有时会导致一些看似奇怪的结果。在理解这两个表达式的行为时,需要深入了解 JS 的类型转换机制以及比较操作符的工作方式。

首先介绍一下 JS 中的类型转换机制,JS 中的类型转换通常发生在两种情况下:隐式类型转换 和 显式类型转换 。隐式类型转换是 JS 自动执行的类型转换,通常发生在需要不同类型的值的运算或比较时。而显式类型转换是通过一些内置函数(如parseInt()、parseFloat()、String()、Number()等)来显式地进行类型转换。

== 的隐式类型转换

特例:

  • null == undefined 为 true;
  • NaN不与任何值相等,包括它自己;
  • null和undefined不会进行数据转换;

1.数值和非数值类型比较

  • 数值和字符串
ini 复制代码
console.log('Ywis' == 1); // false
console.log('' == 0); // true
console.log('1' == 1); // true
console.log('000' == 0); // true

当一个数据类型是数值,另一个是字符串,会将字符串转换为数值,再与之比较。比如其中'Ywis'会转换为数字NaN,所以返回false。

  • 数值和布尔值
arduino 复制代码
console.log(true == 1);  // true
console.log(true == 2);  // false
console.log(false == 0); // true
console.log(false == 1); // false

很容易就能看出,这样的比较,会将true转化成数值1,false转化为0。

  • 数值和数组
arduino 复制代码
console.log([] == 1); // false
console.log([] == 0); // true
console.log(['Ywis'] == 1); // false
console.log([1,2] == 2); // false

在这里,数组会先通过调用toString()转换为字符串后再转化为数值。比如['Ywis']先转化为字符串'Ywis'后再转化为数值NaN,所以返回false。

拓展:数组、对象和函数在与其他基本数据类型进行比较时都会先转换为字符串,然后再转换为相应的数据类型。

2. 布尔值和非布尔值类型比较

arduino 复制代码
console.log(true == 1); // true
console.log(true == '00001'); // true
console.log(false == []); // true
console.log(true == ['Ywis']); // false

当布尔值和非布尔类型比较,会将true转换为 1,false转换为 0。将非布尔值类型统统转化成数值,这里的类型转换规则和上面提到的相同。

3. 对象和原始值的比较

arduino 复制代码
console.log({} == 0); // false
console.log([] == 1); // false

当对象与原始值进行比较时,JS 会先尝试通过调用对象的valueOf()方法来获取原始值。如果valueOf()方法返回的是一个原始值,JS 会将其转换成与待比较的原始值相同的类型,然后进行比较。如果valueOf()方法返回的还是一个对象,则会继续调用对象的toString()方法,将其返回值转换为原始值,然后再进行比较。

比如{} == 0,对于空对象{}它的valueOf() 方法返回的是对象本身,因此 JS 会继续调用 toString() 方法,返回得到一个字符串 "[object Object]",再转换为数值NaN,所以返回false。

逻辑非 ---!

在操作非布尔值类型时,会进行两步操作:

  1. 将该数据类型先转换成布尔值类型。
  2. 再进行取反操作。
arduino 复制代码
console.log(!""); // true
console.log(![]); // false
console.log(!{}); // false
console.log(!(-4)); // false

注意:

  1. false:布尔值 false
  2. undefined:未定义的值
  3. null:空值
  4. 0:数字 0
  5. -0:负零
  6. NaN:非数字值
  7. '':空字符串

除了以上七个值外,其他值(包括对象、数组、函数等)在转换为布尔值时都会返回 true。这种规则使得 JS 中的大多数值被视为真值(truthy)。

面试题讲解🔥🔥🔥

一、 == 为 false

这是很好理解的,在 JS 中对象(包括数组)的比较是基于它们的引用地址,而不是它们的内容。即使两个对象的内容相同,它们的引用地址也不同,所以比较结果是 false。

二、 == ! 为 true

过程:

  1. 因为!的优先级高于==,首先将空数组转换为true,再取反得false;
  2. 接着是[] == false,这是布尔值和非布尔值类型比较,首先将false转换为0,然后调用对象的toString方法,返回一个空对象''
  3. 最后空对象转换为数值0,即 0 == 0,结果返回true。

总结🌸🌸🌸

在面试中,对于类型转换的理解不仅仅是一个基本的知识点,更是一个展示候选人深度理解 JS 语言本质的机会。希望本文能够帮助你更好的理解[] == ![] 中的类型转换机制,在之后的面试之中得心应手,祝你登高望远,心向彼岸。

相关推荐
三十而立洋4 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
晨米酱4 天前
AGENTS.md:Agent 的上下文策略层
面试·架构·agent
卡布鲁4 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄4 天前
JavaScript 隐式全局变量解析
javascript
彧azz4 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
沙蒿同学4 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端
CoderYanger4 天前
A.每日一题:835. 图像重叠
java·开发语言·程序人生·leetcode·面试·职场和发展·学习方法
paopaokaka_luck4 天前
智慧社区综合服务小程序(人脸识别、AI问答、Echarts图形化分析)
前端·javascript·spring boot·spring·数据分析·echarts
爱学习的执念4 天前
助力金九银十1000道软件测试面试题(功能、接口、自动化、WEB、APP.......)附答案
软件测试·面试
小的~~4 天前
银河麒麟V10 ARM部署TDengine(涛思)工业时序数据库安装与测试
面试·程序员创富