在 JavaScript 中,类型转换是一项基本且重要的概念。类型转换可以是自动的,也可以是强制的。自动类型转换发生在 JavaScript 需要在不同类型之间进行操作时,而强制类型转换是由程序员显式实施的。了解如何在不同的数据类型之间转换是每个 JavaScript 开发者必备的技能。
原始值转布尔值
在 JavaScript 中,所有的值都有一个布尔等价值,即它们都可以被强制转换为 true
或 false
。以下值在转换为布尔值时会变成 false
:
0
和-0
null
undefined
NaN
- 空字符串 (
""
)
除这些之外的所有其他值都会被转换为 true
。例如:
scss
Boolean(1); // true
Boolean("hello"); // true
Boolean(""); // false
Boolean(0); // false
原始值转数字
JavaScript 中原始值转数字主要通过 Number()
函数进行,具体规则如下:
true
转为1
,false
转为0
。null
转为0
。undefined
转为NaN
。- 对于字符串,如果是纯数字组成,则转为相应的数字;含有非数字字符,则转为
NaN
;空字符串转为0
。
示例:
javascript
Number(true); // 1
Number(false); // 0
Number(null); // 0
Number(undefined); // NaN
Number("123"); // 123
Number("123abc"); // NaN
Number(""); // 0
原始值转字符串
原始值转字符串相对直观,通常通过 String()
函数进行:
null
转换为"null"
。undefined
转换为"undefined"
。true
转换为"true"
,false
转换为"false"
。- 数字按照通用规则转换为字符串形式。
示例:
scss
String(10); // "10"
String(null); // "null"
String(undefined); // "undefined"
String(true); // "true"
原始值转对象
原始值转换为对象,通常是通过创建相应原始值的包装类实例实现的,比如使用 new String()
, new Number()
或 new Boolean()
。
javascript
var strObj = new String("string"); // String {"string"}
var numObj = new Number(100); // Number {100}
var boolObj = new Boolean(true); // Boolean {true}
注意,这里创建的是对象,而非原始类型。
下面继续解释如何将对象、数组转换为数字、字符串以及布尔值,并且还会探讨一元运算符和二元运算符在类型转换中的应用。
对象转换为数字
当 JavaScript 尝试将一个对象转换成数字时,它会按照以下步骤操作:
- 调用
valueOf()
方法 :JavaScript 会首先查找并调用对象的valueOf()
方法。如果valueOf()
方法存在并返回一个原始值(比如数字、字符串、布尔值等),JavaScript 会将这个原始值转换为数字。 - 调用
toString()
方法 :如果对象的valueOf()
方法不存在,返回的不是原始值,或者对象没有valueOf()
方法,JavaScript 接下来会调用对象的toString()
方法。然后,JavaScript 会尝试将toString()
方法的返回值转换为数字。 - 转换结果 :对于普通对象来说,
valueOf()
方法通常返回对象本身(这不是原始值),而toString()
方法默认返回字符串"[object Object]"
。由于这个字符串不是一个有效的数字表示,所以最终这个转换过程结果为NaN
。
示例解释:
javascript
javascriptCopy code
console.log(Number({})); // NaN
// 解释:对象的 valueOf() 返回对象本身,不是原始值。toString() 返回 "[object Object]",它不是一个有效的数字表示,因此转换结果为 NaN。
数组转换为数字
对于数组转换为数字,JavaScript 的处理流程如下:
- 调用
toString()
方法 :由于数组通常不具有自己的valueOf()
方法(或者说,其valueOf()
方法返回的还是数组本身),JavaScript 会直接调用数组的toString()
方法。 - 转换字符串为数字 :接下来,JavaScript 尝试将
toString()
方法的返回值(一个字符串)转换为数字。 - 转换结果 :对于空数组
[]
,toString()
方法返回的是空字符串""
。空字符串转换为数字等于0
。对于包含单个数字元素的数组(例如[3]
),toString()
返回的是"3"
,这可以被直接转换为数字3
。但对于包含多个元素或非数字元素的数组(例如[1, 2]
或["a"]
),转换结果将是NaN
,因为得到的字符串(如"1,2"
或"a"
)不是有效的数字表示。
示例解释:
javascript
console.log(Number([])); // 0
// 解释:空数组转换为的空字符串 "",空字符串转换为数字为 0。
对象和数组转换成字符串
对象和数组转换成字符串时,基本遵循相同的步骤:
- 调用
toString()
方法。对于对象,默认的toString()
方法会返回格式为 "[object Object]" 的字符串。对于数组,toString()
方法会将数组元素转换为字符串,并用逗号连接。 - 如果
toString()
方法不存在或不返回原始值,JavaScript 会尝试调用valueOf()
方法,并将其返回值转换为字符串。 - 如果这些都不适用,转换失败。
示例:
vbscript
console.log(({}).toString()); // [object Object]
console.log(([]).toString()); // 空字符串
console.log(([1, 2, 3]).toString()); // "1,2,3"
转布尔
javascript
console.log(Boolean({})) // true
console.log(Boolean([])) // true
console.log(Boolean([1, 2, 3])) // true
对象转布尔规则很简单:永远为true,无论对象空与否
一元运算符和类型转换
一元加 (+
) 运算符
一元加运算符会尝试将操作数转换为数字。
示例解释:
arduino
console.log(+{}); // NaN
// 解释:对象无法直接转换为数字,所以结果是 NaN。
console.log(+[]); // 0
// 解释:空数组转换为的空字符串 "",然后空字符串转换为数字为 0。
console.log(+[2]); // 2
// 解释:单元素数组 [2] 转换为字符串 "2",然后 "2" 转换为数字 2。
一元减 (-
) 运算符
一元减运算符会先将操作数转换为数字,然后改变其符号。
示例解释:
arduino
console.log(-{}); // NaN
// 解释:同上,对象转换为数字失败,结果为 NaN。
console.log(-[]); // 0
// 解释:空数组转换为数字后为 0,变号仍是 0。
console.log(-[2]); // -2
// 解释:数组 [2] 转换为数字 2,变号后成为 -2。
二元运算符和类型转换
加法运算符 (+
)
加法运算符会根据操作数的类型决定是进行数字加法还是字符串连接。
示例解释:
arduino
console.log({} + {}); // "[object Object][object Object]"
// 解释:两个对象转换为字符串进行连接。
console.log([] + []); // ""
// 解释:两个空数组转换为空字符串后连接,结果仍然是空字符串。
console.log([2] + [3]); // "23"
// 解释:两个数组转换为字符串 "2" 和 "3" 后进行连接。
console.log(5 + {}); // "5[object Object]"
// 解释:数字和对象相加,对象转换为其字符串表示形式进行连接。
面试官:下面输出结果是什么,并解释其原因 console.log([] == ![])
这个问题是 JavaScript 类型转换和比较机制中的一个经典案例,它涉及到类型强制转换和布尔逻辑的理解。我们将一步步分解这个表达式 [] == ![]
来理解其输出结果。
-
解析右侧表达式
![]
:[]
是一个空数组,而在 JavaScript 中,所有对象(包括数组)在布尔上下文中均被视为true
。![]
对这个布尔值取反,因此结果是false
。
-
解析左侧表达式
[]
:- 左侧的
[]
保持不变,是一个空数组。
- 左侧的
-
比较
[]
和false
:- 当使用双等号
==
比较两个不同类型的值时,JavaScript 会尝试将它们转换为同一类型,然后再进行比较(这就是所谓的类型强制转换)。 - 在这个例子中,JavaScript 会尝试将
[]
(空数组)转换成一个原始值(在比较中通常转换为数字),而空数组转换为数字是0
。 - 同时,布尔值
false
转换为数字时变成0
。
- 当使用双等号
-
比较转换后的结果:
- 经过类型转换,我们比较的是
0 == 0
。 - 这个比较的结果显然是
true
。
- 经过类型转换,我们比较的是