"深入理解JS:类型转换的艺术与科学"

218 阅读4分钟

引言:

由于JavaScript是一种动态类型语言,变量的类型在程序运行时可以自由地改变,这就为类型转换提供了可能性。类型转换可以分为两种:隐式类型转换和显式类型转换。隐式类型转换通常由JavaScript引擎自动执行,而显式类型转换则需要开发者明确地调用相关的函数或方法。本文将详细介绍JavaScript中的类型转换,包括其背后的原理、常见的转换规则以及如何避免类型转换带来的问题。通过阅读本文,你将更加深入地理解JavaScript的类型系统,并能够在实际开发中更加自如地运用类型转换。

显示转换 -- 原始值转原始值

原始值转布尔:Boolean(xxx)

console.log(Boolean(1));
console.log(Boolean(0));
console.log(Boolean(-1));
console.log(Boolean(NaN));
console.log(Boolean('abc'));
console.log(Boolean(''));
console.log(Boolean(false));
console.log(Boolean(undefined));
console.log(Boolean(null));

对应的执行结果:

true
false
true
false
true
false
false
false
false

原始值转数字:Number(xxx)

console.log(Number('123'));
console.log(Number('hello'));
console.log(Number(true));
console.log(Number(false));
console.log(Number(''));
console.log(Number(' '));
console.log(Number(undefined));
console.log(Number(null));

对应执行结果:

123
NaN
1
0
0
0
NaN
0

原始值转字符串:String(xxx)

console.log(String(123));
console.log(String(true));
console.log(String(false));
console.log(String(undefined));
console.log(String(null));

以下均是字符串转换的结果:

image.png

原始值转对象:new Xxx()

直接构造某一种对象即可。为了方便,直接参考类型转换图表

对象转原始值(重点)-- 隐式转换

在 JS 中,当需要将对象转换为原始值时,直接调用对象的 ToPrimitive() 方法来实现这一转换过程。

image.png

image.png

使用抽象方法转换为原始值。

若是不清楚可以自行去中查看 官方文档

ToPrimitive有两种转换:String和Number

1. ToPrimitive(obj, String) ==> String(obj)

如果接收到的是原始值,直接返回值

否则,调用toString 方法,如何得到原始值,返回

否则,调用valueOf 方法,如何得到原始值,返回

报错

2. ToPrimitive(obj, Number) ==> String(obj)

如果接收到的是原始值,直接返回值

否则,调用valueOf 方法,如何得到原始值,返回

否则,调用toString 方法,如何得到原始值,返回

报错

这里注意好valueOf() 和 toString() 方法的调用。

1. valueOf():

只对包装类有用

image.png

2. toString():

所有对象转原始值都会调用toString()

{}.toString() 得到由"[object 和 class 和 ]"组成的字符串

[].toString() 返回由数组内部元素以逗号拼接的字符串

xx.toString() 返回字符串字面量

image.png

3. 对象转布尔,一定是true

一元操作符 +

+[]  ==> 0 的执行过程:
1. ToNumber([])
2. ToPrimitive([], Number)
3. [].valueOf()
4. [].toString()   ===> ''
5. 执行出0

按照上述方法依次执行。

二元操作符 +

执行步骤:

v1 + v2:

lprim = ToPrimitive(v1)

rprim = ToPrimitive(v2)

如果 lprim 或者 rprim 是字符串,那么就ToString(lprim) 或者ToString(rprim) 再拼接

否则,ToNumber(lprim) + ToNumber(rprim)

例如:

1 + '1' ==> '11'

  1. 1 + '1' ==> '11'

  2. ToPrimitive(1) + ToPrimitive('1')

  3. 1 + '1'

  4. ToString(1) + '1'

  5. '1' + '1'

  6. '11'

最后执行出这样结果的由来。

==简介

image.png

所有的步骤均按此而来。

面试题:[] == ! []

  1. ! 运算符! 是逻辑非运算符,它将其操作数转换为布尔值并取反。在这个表达式中,![] 将空数组 [] 转换为布尔值 true,然后取反得到 false
  2. == 运算符== 是宽松等于运算符,它允许在比较中进行类型转换。当比较不同类型的值时,JavaScript会尝试将它们转换为相同类型,然后进行比较。

现在,我们来比较 [] 和 false

  • [] 转换为原始值:由于 [] 是一个对象,== 运算符会尝试将其转换为原始值。根据 ToPrimitive 的规则,首先尝试调用 toString() 方法,对于数组,这通常会返回一个空字符串 ""
  • false 转换为数字:由于 false 是一个布尔值,== 运算符会尝试将其转换为数字。在JavaScript中,false 被转换为数字 0

现在我们比较的是 "" 和 0

  • "" 转换为数字:由于我们正在比较一个字符串和一个数字,== 运算符会尝试将字符串 "" 转换为数字。空字符串转换为数字的结果是 0

最终,我们比较的是 0 和 0,这是一个相等比较,结果是 true

转换我们自己的语言:

ToPrimitive([]) + ToPrimitive({})

  1. [].valueOf() + {}.valueOf()

  2. [].toString() + {}.toString()

  3. '' + '[object Object]'

  4. 最后出:'[object Object]'

总结:

看完此文章最后还需要自行理出符合自己的思路来理解,加深印象!👌😁👌👌👌😁😊