(a == 1 && a == 2 && a == 3)不可以为true?

隐式转换部分规则

JS中使用==对两个值进行比较时,会进行如下操作:

  1. 将两个被比较的值转换为相同的类型。
  2. 转换后(等式的一边或两边都可能被转换)再进行值的比较。

比较的规则如下表(mdn

在这里插入图片描述

为了让(a == 1),a只有这几种:

为String时,并且可转换为数字1('1' == 1 => true
为Boolean时,并且可转换为数字1 (true == 1 => true)
为Object时,通过转换机制后,可转换为数字1 (请看下文

对象转原始类型,执行顺序如下:

  1. Symbol.toPrimitive
  2. valueOf
  3. toString
  4. 报错
const obj = {
    
    
  value: 1,
  valueOf() {
    
    
    return 2
  },
  toString() {
    
    
    return '3'
  },
  [Symbol.toPrimitive]() {
    
    
    return 4
  }
}

obj == 4 // true
// 您可以将Symbol.toPrimitive、toString、valueOf分别注释掉验证转换规则

方法1 (with)

let i = 1
with ({
    
    
  get a() {
    
    
    return i++
  }
}) {
    
    
  if (a == 1 && a == 2 && a == 3) {
    
    
    console.log('去吧,皮卡秋')
  }
}

方法2 (Symbol.toPrimitive)

const a = {
    
    
  i: 1,
  [Symbol.toPrimitive]() {
    
    
    return this.i++
  }
}
if (a == 1 && a == 2 && a == 3) {
    
    
  console.log('去吧,皮卡秋') // 去吧,皮卡秋
}

方法3 (valueOf 或 toString)

let a = {
    
    
  i: 1,
  valueOf() {
    
    
    return this.i++
  }
}
if (a == 1 && a == 2 && a == 3) {
    
    
  console.log('去吧,皮卡秋') // 去吧,皮卡秋
}


方法4 (Array && join)

数组对象在进行隐式转换时,调用toString时还会调用join方法。

let a = [1, 2, 3]
a.join = a.shift
if (a == 1 && a == 2 && a == 3) {
    
    
  console.log('去吧,皮卡秋') // 去吧,皮卡秋
}

方法5(Object.defineProperty)

let _a = 1
Object.defineProperty(window, 'a', {
    
    
  get() {
    
    
    return _a++
  }
})
if (a == 1 && a == 2 && a == 3) {
    
    
  console.log('去吧,皮卡秋') // 去吧,皮卡秋
}

方法6 (Proxy)

let a = new Proxy({
    
     i: 1 }, {
    
    
  get(target) {
    
    
    return () => target.i++
  }
})
if (a == 1 && a == 2 && a == 3) {
    
    
  console.log('去吧,皮卡秋') // 去吧,皮卡秋
}

猜你喜欢

转载自blog.csdn.net/formylovetm/article/details/126340700
今日推荐