前言: 因为平时只在开发业务需求,一些开发时不会用到的js基础也不知不觉被遗忘。 如果一个前端基础不扎实,且平时只会写写vue,这样下去迟早被淘汰。所以有一定危机意识,逐步捡起JavaScript基础是很有必要的。 开搞!
隐式类型转换是什么?
js中各中类型数据在参与运算时,对值类型的自动转换。 尽管开发时会尽量避免不同类型数值的转换,但没办法得应付面试...
1. 字符串类型的隐式转换
结论: 字符串与任何类型数据在进行加法运算时,通常都是字符串拼接的操作(别的数据类型会转换为字符串参与拼接)。 只有在进行- * / 等操作时字符串类型数据才会进行隐式转换。
参与加法运算时
let a = '1';
console.log(a + 1); // '11'
console.log(a + true); // '1true'
console.log(a+ {x: 1}); // '1[Object object]'
console·log(a + []); // '1'
console.log(a + [1]); // '11'
var arr = [1, 2, 3];
console.log(a + arr); 11,2,3
console.log('1' + NaN) '1NaN'
console.log('1' + undefined); // '1undefined'
console.log('1' + null); // '1null'
由此可知,字符串在与任何数据类型进行加法运算都会直接进行字符串拼接操作;而对象和数组有些特殊。 与对象拼接时,会尝试通过valueof来获取对象原始值,如果获取不到,则通过tostring来把对象转换为字符串参与拼接
const obj = {
valueOf: function() {
return 2; // 返回一个原始值
}
};
console.log('1' + obj); // 输出 '12'
--------------------------------------------
const obj = {
toString: function() {
return '[Object object]'; // 返回一个字符串
}
};
console.log('1' + obj); // 输出 '1[Object object]'
与数组拼接时,数组不会调用valueof,会执行一下toString(),将数组转换为字符串参与运算
const arr = [1, 2, 3];
console.log('1' + arr); // 输出 "1,2,3",因为 arr.toString() 返回 "1,2,3"
const arr = [];
console.log('1' + arr) // 1 // 空数组会转换为空字符串''
参与其他运算时
字符串(String) - 两个字符串参与加法以外的运算,会隐式转换为数值
let a = '2';
console.log(a - '1');
// 1
数字(Number) :
- 如果字符串是一个有效的数字,它会被转换为数字类型,然后进行算术运算。
- 如果字符串不是有效的数字,结果会是 `NaN`(Not a Number)。
```
let result = '1' - 1; // 结果是 0
result = '1' * 2; // 结果是 2
result = '1' / 2; // 结果是 0.5
```
布尔值(Boolean) :
- `true` 会被转换为 `1`,`false` 会被转换为 `0`,然后进行算术运算。
```
result = '1' - true; // 结果是 0
result = '1' * false; // 结果是 0
result = '1' / true; // 结果是 1
```
null:
- `null` 会被转换为 `0`,然后进行算术运算。
```
result = '1' - null; // 结果是 1
```
undefined:
- `undefined` 在算术运算中会被转换为 `NaN`。
```
result = '1' - undefined; // 结果是 NaN
```
对象(Object) :
- 对象会尝试通过调用其 `valueOf()` 方法来获取原始值。如果 `valueOf()` 返回的不是原始值,则会调用 `toString()` 方法,然后尝试将得到的字符串转换为数字。
- 如果 `valueOf()` 或 `toString()` 方法不存在,或者它们返回的值无法转换为数字,结果会是 `NaN`。
```
result = '1' - {}; // 结果是 NaN,因为 {} 的 toString() 返回 "[object Object]",无法转换为数字
```
数组(Array) :
- 数组会被转换为字符串(通常是逗号分隔的元素列表),然后尝试将这个字符串转换为数字。
- 如果数组为空或者包含的元素无法转换为有效的数字,结果会是 `NaN`。
```
result = '1' - []; // 结果是 1,因为 [] 的 toString() 返回 "",空字符串转换为数字是 0
result = '1' - [1]; // 结果是 0,因为 [1] 的 toString() 返回 "1",然后 '1' - '1' 变成了 0
```
在出去加法外的所有情况下,如果字符串不能被解析为一个有效的数字,或者运算结果不明确,最终的结果将是 NaN。
2. 数值类型的隐式转换
加法 (+)
-
数字 + 字符串:结果是一个字符串,数字会被转换为字符串。
5 + '5' // "55" -
数字 + 布尔值:
true转换为1,false转换为0。5 + true // 6 5 + false // 5 -
数字 +
null或undefined:null转换为0,undefined转换为NaN。5 + null // 5 5 + undefined // NaN -
数字 + 对象:对象会尝试转换为原始值(通常是字符串)。
5 + {} // "5[object Object]" 5 + [] // "5"
减法 (-), 乘法 (*), 除法 (/)
-
数字 - 字符串/布尔值/null/undefined/对象:这些值会被转换为数字(如果可能的话)。
5 - '3' // 2 5 - true // 4 5 - null // 5 5 - undefined // NaN 5 - {} // NaN -
数字 * 字符串/布尔值/null/undefined/对象:这些值会被转换为数字(如果可能的话)。
5 * '2' // 10 5 * false // 0 5 * null // 0 5 * undefined // NaN 5 * {} // NaN -
数字 / 字符串/布尔值/null/undefined/对象:这些值会被转换为数字(如果可能的话)。
5 / '2.5' // 2 5 / true // 5 5 / null // Infinity 5 / undefined // NaN 5 / {} // NaN
算数运算中, 隐式类型转换时,默认会转换为0 的如下:
' ', '', null, '0', false, []
undefined, 与 {} 参与算数逻辑运算,默认转换为NaN undefined 含义为未定义, 并没有原始值,所以无法转换为数值
对于空对象 {}:
toString方法通常返回一个字符串,表示对象类型,例如"[object Object]"。valueOf方法返回对象本身。
在算术运算中,JavaScript 首先尝试使用 valueOf 方法将对象转换为原始值,如果结果是对象,则尝试使用 toString 方法。然后将得到的字符串尝试转换为数字。由于 "[object Object]" 不能直接转换为有效的数字,所以结果通常是 NaN。
同上面类似,如果自定义了对象中的valueof方法并返回数值,对象会转换为数值参与算数运算
var obj = {
valueOf: function() {
return 1;
}
};
console.log(5 + obj); // 输出 6,因为 obj.valueOf() 返回 1,然后进行 5 + 1 的运算
console.log(5 - obj); // 输出 4,因为 obj.valueOf() 返回 1,然后进行 5 - 1 的运算
总结
- 字符串在与不同类型参与加法运算时,会默认进行字符串拼接操作
- 字符串在参与其他算数运算时,会尝试转换为数值,否则会转换为NaN
- 数值类型在与除字符串外类型数据参与运算时,会尝试将其他类型转换为数值,否则NaN
- 在与数值参与算数运算时,其他类型数据隐式转换为0的有: ' ', '', null, '0', false, []
- 对象在参与隐式转换时,会尝试通过valueof来获取对象原始值,如果获取不到,则通过tostring来把对象转换为字符串参与拼接(valueof 和tostring 均可以重写来自定义返回值类型)
- 判断值是否相等时需要用===全等来判断,== 不严格等于号也会对两边的值进行隐式转换