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

前言

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

下面是一道面试题

console.log([]==![])

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

类型转换

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

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

Number

https://es5.github.io/#x9.3
这是官方的文档,看不懂没关系,我带着你一起解读。

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

    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方法

image.png

基本数据类型基本都是直接变成字符串,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类型是最简单的,基本数据类型直接上图。

image.png

重点是对象类型转为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,下机!

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

  • 39
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

绯雨934

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值