songning0605 / blog

整理记录
1 stars 0 forks source link

js隐式类型转换之 a == 1 && a == 2 && a == 3 返回true #6

Open songning0605 opened 4 years ago

songning0605 commented 4 years ago
const a = {
  i: 1,
  toString: function () {
    return a.i++;
  }
}
if (a == 1 && a == 2 && a == 3) {
  console.log('hello world!');
}

解析

  1. 当执行a == 1 && a == 2 && a == 3 时,会从左到右一步一步解析,首先 a == 1,会进行 ToPrimitive(a, Number) == 1 转换。

  2. ToPrimitive(a, Number),按照上面原始类型转换规则,会先调用valueOf方法,a的valueOf方法继承自Object.prototype。返回a本身,而非原始类型,故会调用toString方法。

  3. 因为toString被重写,所以会调用重写的toString方法,故返回1,注意这里是i++,而不是++i,它会先返回i,在将i+1。故ToPrimitive(a, Number) = 1。也就是1 == 1,此时i = 1 + 1 = 2。

  4. 执行完a == 1返回true,会执行a == 2,同理,会调用ToPrimitive(a, Number),同上先调用valueOf方法,在调用toString方法,由于第一步,i = 2此时,ToPrimitive(a, Number) = 2, 也就是2 == 2, 此时i = 2 + 1。

  5. 同上可以推导 a == 3也返回true。故最终结果 a == 1 && a == 2 && a == 3返回true