面试官:谈谈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