前言
OK,又是在学习的路上遇到了难点,今天拿来分享一哈。ok,话不多说,开始分享。
下面是一道面试题
console.log([]!==[])
你觉得上面的值打印为多少?我告诉你,打印的结果是true
。如果你是猜对的或者不会可以看看我对这个问题的深度解剖,如果有大哥已经了解也欢迎在评论区指教一哈。
类型转换
这里我们只聊Number,String,Boolean类型的类型转换。其他的基本类型Undefined和NULL不太具有讨论意义,这里就不进行讨论。
要搞懂类型转换,官方文档必不可少。
Number
https://es5.github.io/#x9.3
这是官方的文档,看不懂没关系,我带着你一起解读。
-
在遇到类型转换的时候会触发
ToNumber
方法
Undefined
:直接返回NAN
NULL
:返回 0Boolean
:true
返回 1,false
返回 0.Number
:直接返回String
:总结一句话,只要有非数字就返回NAN,其他就返回数字(空字符串返回的是0)Object(对象)
:在对对象类型进行基本数据类型转换,ToNumber
会调用ToPrimitive
方法
ToPrimitive(argument,type)
ToPrimitive方法有两个参数一个是argument
(类型转换的参数),另一个type
是你要转换的类型。
ToNumber
调用ToPrimitive
方法实际就是将要类型转换的对象变量和转换类型传给ToPrimitive方法接受返回值然后继续进行ToNumber的基本类型判断转换。
那么ToPrimitive会干一件什么事情呢?
- ToPrimitive(obj,[原始类型])
- 判断接收到的值是不是原始类型,是则直接返回
- 否,则调用valueOf方法,如果得到了原始值,则返回
- 否,则调用toString()方法,如果得到原始值,则返回
- 如果还没有获得返回值则报错
以上就是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([] == ![] );
解析:
此表达式[] == ![]
中涉及了多个转换步骤,让我们逐一解析:
-
右侧表达式
![]
的解析:[]
是一个空数组,属于对象类型。在布尔类型转换时,所有对象(包括数组)都被视为true
。- 因此,
![]
实际上是对一个布尔值true
应用逻辑非操作,得到false
。
-
左侧表达式
[]
保持不变,仍为一个空数组。 -
比较阶段:
[] == false
:- 在使用
==
进行比较时,会进行类型转换以达到可比性。这里涉及两种不同类型:一个是对象(空数组),另一个是布尔值。 - 对于这样的比较,JavaScript 会尝试将两边转换为同一类型(Number类型)再比较。首先,布尔值
false
会被转换为数字0
(因为在布尔到数字的转换中,true
转为1
,false
转为0
)。 - 接下来,需要将左边的空数组转换为数字。这通过调用
ToPrimitive
并尝试valueOf()
和toString()
方法实现。对于数组,valueOf()
不改变其原始值(依然为数组),因此会继续调用toString()
,空数组[]
经过toString()
转换后得到空字符串''
。 - 空字符串
''
再通过ToNumber('')
转换为数字,空字符串对应的数字是0
。
- 在使用
结论:因此,[]
经过一系列转换后被视为 0
,与 false
经过转换后的 0
相等。
所以答案是 true
至此数据类型转换全部搞定!
结语
深入理解这些原理不仅能够提升代码质量,还能让我们在面对复杂逻辑时游刃有余。掌握类型转换的规则是每位JavaScript开发者通往高手之路的必修课。ok,下机!
本篇文章创作不易,喜欢的话就请点个赞吧。谢谢各位大哥>_<.