面试官:谈谈JS中的类型转换在JavaScript中,类型转换是一个常见但复杂的话题。本文将详细介绍JavaScript
在JavaScript中,类型转换是一个常见但复杂的话题。本文将详细介绍JavaScript中的类型转换,包括原始值之间的转换、对象到原始值的隐式转换,以及运算符在类型转换中的表现。
原始值之间的转换
JavaScript提供了三个构造函数来处理原始值之间的类型转换:Boolean(x)
、Number(x)
和 String(x)
。这些函数可以显式地将一个值转换为布尔值、数字或字符串。
-
转换为布尔值:
Boolean(x)
Boolean(x)
将任何值转换为布尔值。几乎所有的值都会被转换为true
,除了以下几个:false
、0
、-0
、0n
(BigInt zero)、""
(空字符串)、null
、undefined
、和NaN
,什么值也不传也是false。
-
转换为数字:
Number(x)
Number(x)
将值转换为数字。字符串中的数字字符会被解析为对应的数字值,而空字符串会转换为0
。布尔值true
和false
分别转换为1
和0
。null
转换为0
,而undefined
和字符串中不是纯数字的话会转换为NaN
。
-
转换为字符串:
String(x)
String(x)
将值转换为字符串。除了null
和undefined
分别转换为"null"
和"undefined"
之外,其他原始值都被转换为它们的字符串表示形式。
对象到原始值的隐式类型转换
当JavaScript需要将对象转换为原始值时,会调用内部的 ToPrimitive
函数。这个函数会根据需要转换的目标类型不同,采取不同的步骤。注意ToPrimitive
是JavaScript引擎内部使用的一个抽象操作,并不是给我们用户使用的(包括下面的ToNumber
和ToString
)。
转换为数字
当需要将对象转换为数字时,JavaScript会调用 ToNumber
函数,而 ToNumber
函数会调用 ToPrimitive
函数,传入类型提示 Number
。
ToPrimitive(obj, Number)
的步骤如下:
- 如果
obj
是原始类型,直接返回。 - 否则,调用
valueOf
方法,如果返回原始值,则返回该值。 - 否则,调用
toString
方法,如果返回原始值,则返回该值。 - 如果仍然没有得到原始值,则抛出错误。
转换为字符串
当需要将对象转换为字符串时,JavaScript会调用 ToString
函数,而 ToString
函数会调用 ToPrimitive
函数,传入类型提示 String
。
ToPrimitive(obj, String)
的步骤如下:
- 如果
obj
是原始类型,直接返回。 - 否则,调用
toString
方法,如果返回原始值,则返回该值。 - 否则,调用
valueOf
方法,如果返回原始值,则返回该值。 - 如果仍然没有得到原始值,则报错。
转换为布尔值
任何对象转换为布尔值都会返回 true
。
toString
上面提到的 toString
根据类型的不同,调用的方法也不同。
Object.prototype.toString()
返回形如"[object xxxx]"
样的字符串。Array.prototype.toString()
返回一个由数组内部的元素以逗号拼接的字符串。- 其他:
Xxxx.prototype.toString()
返回一个字符串字面量。
上一篇类型判断的文章有详细介绍,小伙伴们可以去看一看。
运算符与类型转换
一元运算符 +
一元运算符 +
会触发隐式类型转换,将操作数转换为数字。例如,+"123"
会返回数字 123
,而 +true
会返回 1
。
二元运算符 +
二元运算符 +
的行为取决于操作数的类型。如果其中一个操作数是字符串,另一个操作数会被转换为字符串并进行字符串连接。例如,"1" + 2
会返回 "12"
。如果两个操作数都不是字符串,则会将它们转换为数字进行相加。
栗子
说了那么多,我们来实战几题
console.log('1' + 1 );
console.log(1 + []);
console.log({}+[]);
小伙伴们可以在心里想想上面的代码分别会输出什么。
公布答案
分别输出了字符串11,字符串1和字符串[object Object]
相等运算符:==
vs ===
==
(宽松相等):会触发隐式类型转换,以数字为标准。例如,"1" == 1
会返回true
,因为字符串"1"
被转换为了数字1
。===
(严格相等):不会触发类型转换。只有当两个值类型相同且内容相同时,才会返回true
。例如,"1" === 1
会返回false
,因为一个是字符串,另一个是数字。
栗子
再来一题稍微难一点的
console.log([] == ![]);
会输出true还是false呢?如果没看这一篇文章的话,乍一眼看上去,很多人都会觉得输出false是吧,但是看完这篇文章的你不一样,让我们来冷静分析一下。
- 首先,!优先级更高,所以先把!旁边的[]转为布尔类型,因为任何对象转布尔类型都是true,![] -> !true -> false,等式变为[]==false
- 接下来把两边分别转换为数字类型,[] -> '' -> 0
- false -> 0。最后等式就变成了0==0,结果当然是true。
结语
本文介绍了原始值之间的转换、对象到原始值的隐式类型转换,以及运算符在类型转换中的表现。希望看了本片文章,能让你在处理类型转换时更加得心应手。
转载自:https://juejin.cn/post/7408821833552183322