(a ==1 && a== 2 && a==3) 怎样才能为true?

一个有趣的问题:

在 JavaScript 中, (a ==1 && a== 2 && a==3) 是否有可能为 true ?      

解法一:利用松散相等运算符 == 的工作原理

你可以简单地创建一个带有自定义toString( 或者 valueOf)函数的对象,在每一次使用它时候改变它所的返回值,使其满足所有三个条件。

const a = {

  i: 1,

  toString: function () {

    return a.i++;

  }

}

if(a == 1 && a == 2 && a == 3) {

  console.log('Hello World!');

}

// Hello World!

之所以会得到如此结果,是由于表达式中使用了松散相等的运算符 ==。使用松散相等时,如果其中一个操作数与另一个类型不同,则 JS 引擎将尝试将一个操作转换为另一个类型。在左边对象、右边的数字的情况下,它会尝试将对象转换为一个数,首先通过调用 valueOf 如果是可调用的。否则,它会调用toString方法。如果我不从toString返回一个字符串(而是返回数字),JS 引擎会尝试将字符串转换为一个数字,虽然有一个稍长的路径,但它仍然会给我们同样的结果。

解法二:利用Object.defineProperty  方法:

var val = 0;

Object.defineProperty(window, 'a', {

  get: function() {

    return ++val;

  }

});

if (a == 1 && a == 2 && a == 3) {

  console.log('yay');

}

使用一个get,让 a 的返回值为三个不同的值。然而这并不意味着我们应该在真正的代码中使用。。。

。 

总结:

1. 利用松散相等运算符 == 的原理,自定义 toString 和 valueOf 返回对应值

2. 劫持 JS 对象的 getter,不过这种方式对于严格相等 === 同样有效

你可能感兴趣的:(javascript)