JavaScript在计算比较的过程中,有时候会发生数据类型转换,比如:
const arr = [1];
const num = 2;
arr + num // '12'
以上只是举一个类型转换的例子,js中有两大类数据类型,其中string、number、boolean、undefined、null、symbol是基本数据类型、object是复杂数据类型(栈中存储数据的堆中的地址)
转Boolean
在js中,只有null
,undefined
,NaN
,false
,''
,0
,+0
,-0
转换为Boolean是false
,其他一律是true
,包括所有对象。
Boolean([]) // true
Boolean({}) // true
对象转换基本
对象在转换基本数据类型的时候会 优先调用valueOf方法,然后调用toString方法,这两个方法可以重写,
当然也可以重写Symbol.toPrimitive
方法,这个方法优先级最高。该方法在对象转换成原始数据类型的时候会调用,会接受一个字符串参数,表示当前运算的模式,一个有三种模式。
- Number:该场合需要转成数值
- String:该场合需要转成字符串
- Default:该场合可以转成数值,也可以转成字符串。
// 拥有 Symbol.toPrimitive 属性的对象
let obj = {
[Symbol.toPrimitive](hint) {
if(hint === 'number'){
console.log('Number场景');
return 123;
}
if(hint === 'string'){
console.log('String场景');
return 'str';
}
if(hint === 'default'){
console.log('Default 场景');
return 'default';
}
}
}
console.log(2*obj); // Number场景 246
console.log(3+obj); // String场景 3default
console.log(obj + ""); // Default场景 default
console.log(String(obj)); //String场景 str
四则运算转换
在加法运算中,类型转换有以下特规则
- 运算中其中一方为字符串,那么就会把另一方也转换为字符串
- 如果一方不是字符串或者数字,那么会将它转换为数字或者字符串 ```javascript // 1转换成’1’ 1 + ‘1’ // ‘11’
// true转换成1 true + true // 2
// [1,2,3]用toString转换成’1,2,3’ 4 + [1,2,3] // “41,2,3”
// + ‘转换成’NaN’ ‘a’ + + ‘b’ // -> “aNaN”
// ‘3’ => 3 4 * ‘3’ // 12
// [] => 0 4 * [] // 0
// [1, 2] => NaN 4 * [1, 2] // NaN
<a name="5PoME"></a>
## 比较运算符
- 如果是对象,就通过 toPrimitive 转换对象
- 如果是字符串,就通过 unicode 字符索引来比较
```javascript
[] == ![] // -> true
// 转换过程
// [] 转成 true,然后取反变成 false
[] == false
// 根据第 8 条得出
[] == ToNumber(false)
[] == 0
// 根据第 10 条得出
ToPrimitive([]) == 0
// [].toString() -> ''
'' == 0
// 根据第 6 条得出
0 == 0 // -> true