为何 a==1 && a==2 && a==3 为 true?

这是在面试题里看到的,原文是说如何让 a==1 && a==2 && a==3true

以下是答案:

let a = [3, 2, 1]
a.__proto__.toString = function() {
    return a.pop()
}

打印 console.log(a==1 && a==2 && a==3) 结果真为 true

朋友说 ==进行隐式转换,调用了 toString 方法,但是还不大清楚,所以请各位前辈指教

阅读 3.6k
6 个回答

== 判断,一边为 Number 类型,则会把两边都进行一个数值转换,数值转换会先调用 valueOf 函数,数组调用 valueOf 后返回的还是数组本身,就会再次调用 toString 函数,而

a.__proto__.toString = function() {
    return a.pop()
}

重写了 atoString 函数,所以打印的语句可以看成

console.log((a.pop())==1 && (a.pop())==2 && (a.pop())==3)
//pop是从数组末尾弹出最后一个元素,修改原数组,并返回弹出的元素
//所以 (a.pop())==1 ==>  1==1 然后a变成[3,2],以此类推2,3也是如此
  1. a==1,调用a.valueOf(),跟1不等,再调用a.toString(),得到1,与1相等,返回true,继续往后,此时a=[3,2]
  2. a==2,同上,继续往后,此时a=[3]
  3. a==3,同上,得到true

这个问题其实还是能考到对 Javascript 的基本理解的,而不是纯粹为了玩。
其一,对于一个对象做比较有 valueOf/toString 的调用问题。
其二,JS 里一个变量背后经常是一个 function。
自定义 toString(或者 valueOf)方法,每次调用改变一次返回值,从而满足判断条件。


const a = {
  i: 1,
  toString: function () {
    return a.i++;
  }
}

if(a == 1 && a == 2 && a == 3) {
  console.log('Hello World!');
}

当使用 == 时,如果两个参数的类型不一样,那么 JS 会尝试将其中一个的类型转换为和另一个相同。在这里左边对象,右边数字的情况下,会首先尝试调用 valueOf(如果可以调用的话)来将对象转换为数字,如果失败,再调用 toString。

我只是一个搬运工
can-a-1-a-2-a-3-ever-evaluate-to-true

复制代码并运行 -.-
var a= 1;
var a‍= 2;
var a‍‍= 3;
if(a==1&&a‍==2&&a‍‍==3) {
    console.log("Why hello there!")
}

算术运算符优先级吧 == 的运算优先级低于 &&
a==1&&a==2&&a==3
实际运算顺序是
a==(1&&a==(2&&a==3))
所以a=3就可以满足结果为true

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题