JS类型转换面试题:[] == ![] 为true?

前言

OK,又是在学习的路上遇到了难点,今天拿来分享一哈。ok,话不多说,开始分享。

下面是一道面试题

复制代码
console.log([]!==[])

你觉得上面的值打印为多少?我告诉你,打印的结果是true。如果你是猜对的或者不会可以看看我对这个问题的深度解剖,如果有大哥已经了解也欢迎在评论区指教一哈。

类型转换

这里我们只聊Number,String,Boolean类型的类型转换。其他的基本类型Undefined和NULL不太具有讨论意义,这里就不进行讨论。

要搞懂类型转换,官方文档必不可少。

Number

https://es5.github.io/#x9.3

这是官方的文档,看不懂没关系,我带着你一起解读。

  1. 在遇到类型转换的时候会触发ToNumber方法

    1. Undefined:直接返回NAN
    2. NULL :返回 0
    3. Booleantrue返回 1, false返回 0.
    4. Number:直接返回
    5. String:总结一句话,只要有非数字就返回NAN,其他就返回数字(空字符串返回的是0)
    6. Object(对象):在对对象类型进行基本数据类型转换,ToNumber会调用ToPrimitive方法

ToPrimitive(argument,type)

ToPrimitive方法有两个参数一个是argument(类型转换的参数),另一个type是你要转换的类型。
ToNumber调用ToPrimitive方法实际就是将要类型转换的对象变量和转换类型传给ToPrimitive 方法接受返回值然后继续进行ToNumber的基本类型判断转换

那么ToPrimitive会干一件什么事情呢?

  • ToPrimitive(obj,[原始类型])
  1. 判断接收到的值是不是原始类型,是则直接返回
  2. 否,则调用valueOf方法,如果得到了原始值,则返回
  3. 否,则调用toString()方法,如果得到原始值,则返回
  4. 如果还没有获得返回值则报错

以上就是Number类型转换全部步骤,接下来做题测试题看你是否掌握。

例题

复制代码
console.log( +[] );
console.log( +{} );

解析

这里的+号会触发隐式类型转换,你可以理解为Number(),这里的[](数组) 和 {} (对象) 都是属于对象类型,所以会触发ToPrimitive方法直到toString()得到返回值,[]将会变成空字符串''

而对象{}将会变成字符串'[object Object]',继续对ToPrimitive 得到的返回值字符串进行ToNumber 类型转换,空字符串将会变成0 ,而'[object Object]'将会变成NAN

所以答案打印的值一个为 0,一个为 NAN

String

String类型转换和Number数据类型转换方法基本一致。String类型转换调用的是ToString方法

基本数据类型 基本都是直接变成字符串,String类型就是直接不进行转换之间返回。对象类型也同样是调用ToPrimitive进行转换之后进行返回。但是唯一不同的是ToPrimitive步骤的2,3步,是直接调用toString方法而不是先调用valueOf方法。其他基本一致。

下面是例题

例题

复制代码
console.log( 1+{} );

解析

在表达式1 + {}中,+操作符根据其两侧的操作数类型执行不同的操作。如果一侧是字符串,+将执行字符串拼接;如果两侧都是数字,则执行加法运算。在这里,因为{}是一个对象,它首先会通过类型转换尝试成为可以与数字相加的形式。

对于对象{},当我们尝试将其与数字进行加法操作时,JavaScript引擎会调用该对象的toString()方法来获取一个可以与数字相加的字符串表示。对于一个空对象,toString()方法默认返回'[object Object]'

因此,{}通过toString()转换为字符串'[object Object]'。此时,加法操作实际上是字符串'1'(数字1转换为字符串)与'[object Object]'的拼接。

所以答案打印的值为 '1[object Object]'

Boolean

Boolean类型是最简单的,基本数据类型直接上图。

重点是对象类型转为Boolean类型的时候,无论对象类型是啥统一全部为true,记住全部为true.

到此为止Number,String,Boolean的数据类型转换。你已经全部学完,回到标题这题

例题

复制代码
console.log([] == ![] );

解析:

此表达式[] == ![]中涉及了多个转换步骤,让我们逐一解析:

  1. 右侧表达式 ![] 的解析

    • [] 是一个空数组,属于对象类型。在布尔类型转换时,所有对象(包括数组)都被视为 true
    • 因此,![] 实际上是对一个布尔值 true 应用逻辑非操作,得到 false
  2. 左侧表达式 [] 保持不变,仍为一个空数组

  3. 比较阶段:[] == false

    • 在使用 == 进行比较时,会进行类型转换以达到可比性。这里涉及两种不同类型:一个是对象(空数组),另一个是布尔值。
    • 对于这样的比较,JavaScript 会尝试将两边转换为同一类型(Number类型)再比较。首先,布尔值 false 会被转换为数字 0(因为在布尔到数字的转换中,true 转为 1false 转为 0)。
    • 接下来,需要将左边的空数组转换为数字。这通过调用 ToPrimitive 并尝试 valueOf()toString() 方法实现。对于数组,valueOf() 不改变其原始值(依然为数组),因此会继续调用 toString(),空数组 [] 经过 toString() 转换后得到空字符串 ''
    • 空字符串 '' 再通过 ToNumber('') 转换为数字,空字符串对应的数字是 0

结论 :因此,[] 经过一系列转换后被视为 0,与 false 经过转换后的 0 相等。

所以答案是 true

至此数据类型转换全部搞定!

结语

深入理解这些原理不仅能够提升代码质量,还能让我们在面对复杂逻辑时游刃有余。掌握类型转换的规则是每位JavaScript开发者通往高手之路的必修课。ok,下机!

本篇文章创作不易,喜欢的话就请点个赞吧。谢谢各位大哥>_<.

相关推荐
辻戋15 小时前
从零实现React Scheduler调度器
前端·react.js·前端框架
徐同保15 小时前
使用yarn@4.6.0装包,项目是react+vite搭建的,项目无法启动,报错:
前端·react.js·前端框架
Qrun16 小时前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp16 小时前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.17 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl19 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫21 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友21 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理1 天前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻1 天前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js