likes
comments
collection
share

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

作者站长头像
站长
· 阅读数 66

前言

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

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

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

类型转换

这里我们只聊Number,String,Boolean类型的类型转换。其他的基本类型Undefined和NULL不太具有讨论意义,这里就不进行讨论。 要搞懂类型转换,官方文档必不可少。

Number

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

  1. 在遇到类型转换的时候会触发ToNumber方法 JS类型转换面试题:[] == ![] 为true?

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

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

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

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

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

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

转载自:https://juejin.cn/post/7378028569690390569
评论
请登录