JS中使用==对两个值进行比较时,会进行如下操作:
比较的规则如下表(mdn)

为了让(a == 1),a只有这几种:
为String时,并且可转换为数字1('1' == 1 => true)
为Boolean时,并且可转换为数字1 (true == 1 => true)
为Object时,通过转换机制后,可转换为数字1 (请看下文)
对象转原始类型,执行顺序如下:
const obj = {
value: 1,
valueOf() {
return 2
},
toString() {
return '3'
},
[Symbol.toPrimitive]() {
return 4
}
}
obj == 4 // true
// 您可以将Symbol.toPrimitive、toString、valueOf分别注释掉验证转换规则
let i = 1
with ({
get a() {
return i++
}
}) {
if (a == 1 && a == 2 && a == 3) {
console.log('去吧,皮卡秋')
}
}
const a = {
i: 1,
[Symbol.toPrimitive]() {
return this.i++
}
}
if (a == 1 && a == 2 && a == 3) {
console.log('去吧,皮卡秋') // 去吧,皮卡秋
}
let a = {
i: 1,
valueOf() {
return this.i++
}
}
if (a == 1 && a == 2 && a == 3) {
console.log('去吧,皮卡秋') // 去吧,皮卡秋
}
数组对象在进行隐式转换时,调用toString时还会调用join方法。
let a = [1, 2, 3]
a.join = a.shift
if (a == 1 && a == 2 && a == 3) {
console.log('去吧,皮卡秋') // 去吧,皮卡秋
}
let _a = 1
Object.defineProperty(window, 'a', {
get() {
return _a++
}
})
if (a == 1 && a == 2 && a == 3) {
console.log('去吧,皮卡秋') // 去吧,皮卡秋
}
let a = new Proxy({ i: 1 }, {
get(target) {
return () => target.i++
}
})
if (a == 1 && a == 2 && a == 3) {
console.log('去吧,皮卡秋') // 去吧,皮卡秋
}