类型转换
转Boolean
在条件判断时,除了undefined,null,false,NaN, '', 0, -0,其他值都转为true,所有对象都转为true
对象转基本类型
对象转基本类型会调用valueOf(),没有的情况下调用toString(),优先级最高的是Symbol.toPrimitive()
let a = {
valueOf() {
return 1
},
toString() {
return "haha"
},
[Symbol.toPrimitive]() {
return 2 // 优先级最高
}
}
a == 2 // true
- 实现a == 1 && a == 2为true
let a = {
value: 1,
[Symbol.toPrimitive]() {
return this.value++ // 优先级最高
}
}
a == 1 && a == 2 // true
- 是否能实现 a === 1 && a === 2 为true
// 由于严格相等不会类型转换,我们可以通过属性描述符get实现
let value = 1
Object.defineProperty(window, "a", {
get() {
return value++
}
})
a === 1 && a === 2 // true
四则运算时类型转换
- 只有当加法运算时,一方是字符串类型,另一方也会转为字符串类型。其他只要其中一方是数字,另一方就转为数字。
- 加法运算会触发三种类型转换:值转为原始值,转换为数字,转换为字符串
1 + "1" // "11"
2 * "2" // 4
[1, 2] + [1, 2] // "1,21,2"
// 会触发toString方法,[1, 2].toString() => "1,2"
- 注意 "a" + + "b"
"a" + + "b" // NaN // 因为 +"b"会返回NaN
== 运算符的转换
比较 x == y
- x,y类型相同就直接进行比较, 注意NaN == NaN(false)
- 如果x,y为null或undefined,注意null == undefined(true)
- x为Number,y为String,那么toNumber(y)在进行比较
- 如果x为Boolean,就toNumber(x)再进行比较
如果x为String或者Number或者Boolean,y为Object,就toPrimitive(y)在进行比较
分析[] == ![] 为true的原因
// [] 转bool是true,然后![]就是false [] == false [] == 0 // boolean转number toPrimitive([]) == 0 // [].toString => '' '' == 0 // toNumber('') => 0 0 == 0 // true
比较运算符
- 数字通过大小比较
- 字符串通过unicode大小比较
- 对象则通过toPrimitive返回后比较大小