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,下机!

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

相关推荐
下雪天的夏风1 分钟前
React@16.x(55)Redux@4.x(4)- store
前端·javascript·react.js
玖玥西1 小时前
html5——CSS3_文本样式属性
前端·css·html·css3·html5·web
卓卓没头发1 小时前
Vue Router 4:构建高效单页面应用的路由管理
前端·javascript·vue.js
SuGarSJL4 小时前
npm ERR! code ENOTEMPTY npm ERR! syscall rename npm ERR!
前端·npm·node.js
tonylua5 小时前
Python: 从 2.7 升级到 3,我比 vue 慢了一点点
开发语言·前端·javascript·vue.js·python
daban20085 小时前
【技术支持】npm镜像设置
前端·npm·node.js
周bro5 小时前
vue2实现复制,粘贴功能,使用vue-clipboard2插件
前端·javascript·vue.js
牛奶味的团子6 小时前
添加点击跳转页面,优化登录和注册页路由
前端·javascript·vue.js
北城南笙-小码农6 小时前
vue3 两个组件之间传值
前端·javascript·vue.js
reembarkation6 小时前
vue 导出excel乱码问题
前端·javascript·vue.js