面试题:为什么[ ] == [ ] 为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转化成数值1false转化为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 语言本质的机会。希望本文能够帮助你更好的理解[] == ![] 中的类型转换机制,在之后的面试之中得心应手,祝你登高望远,心向彼岸。

相关推荐
AndyGoWei31 分钟前
react react-router-dom history 实现原理,看这篇就够了
前端·javascript·react.js
小仓桑35 分钟前
深入理解 JavaScript 中的 AbortController
前端·javascript
换个名字不能让人发现我在摸鱼37 分钟前
裁剪保存的图片黑边问题
前端·javascript
小牛itbull40 分钟前
Mono Repository方案与ReactPress的PNPM实践
开发语言·前端·javascript·reactpress
云和数据.ChenGuang1 小时前
运维面试题.云计算面试题集锦
面试·运维面试题·云计算面试题·linux面试题
小宋10211 小时前
实现Excel文件和其他文件导出为压缩包,并导入
java·javascript·excel·etl
码喽哈哈哈1 小时前
day01
前端·javascript·html
mubeibeinv2 小时前
分页/列表分页
java·前端·javascript
林太白2 小时前
js属性-IntersectionObserver
前端·javascript
爱吃羊的老虎2 小时前
【WEB开发.js】getElementById :通过元素id属性获取HTML元素
前端·javascript·html