一个javascript题目,如何让a == 1 && a == 2 && a == 3为true?
常年行走江湖,碰到看似不可能的事情,人就会变得不会轻易的肯定或否定,那这个题目呢,有可能为true么。这是一篇技术文,不是哲学文,先说答案,可以做到,至于怎么做,下面慢慢说。
即使是刚学javascript的也知道,判断相等有两种方法,一种是===全等,一种是==相等,区别在于会不会发生类型转换。提示到这里大多数人就明白了,a肯定不是数字,再进一步想想,也不是字符串,这两种是实现不了题目效果的。
那别的类型是怎么和数字比较的,翻翻高程,p52,原来布尔值也不行。那其他类型还是有希望的,要先调用valueOf。我们可以在这里做点手脚,比如:
let a = [3, 2, 1]
a.__proto__.valueOf = function() {
return a.pop()
}
直接打印a.valueOf还是会得到这个数组,关于valueOf各位自己查查mdn的说明,顺便查查toString,上面的操作也可以写成:
let a = [3, 2, 1]
a.__proto__.toString = function() {
return a.pop()
}
我这里只演示用数组,a也可以是对象,函数,给一个通用的写法:
let i = 0
let a = new Set()
a.__proto__.valueOf = function() {
i++
return i
}
a就几乎可以随意声明了。
题目用到的知识比较进阶,需要对js有一定了解,如果想了半天没想出来,那可以抓住弱类型喷一下以泄心头之恨,手动滑稽。
2018-03-04
// 如果要求不使用__proto__,可以写setPrototypeOf,官方推荐写法:
let i = 0
let a = {}
let todo = {
toString: function() {
i++
return i
}
}
Object.setPrototypeOf(a, todo)
console.log(a == 1 && a== 2);
参考资料
《javascript高级程序设计》p30,p35,p51
《ECMAScript 6 入门》第9章