请...听...题...
如何让 a == 1 && a == 2 && a == 3 的运行结果是true ?
如果此时你的表情是
那你可以把这边文章X掉安心搬砖了
如果你的表情是
那你可得认真看下去
我们来分析一下,若想 a == 1 && a == 2 && a == 3
成立无非三种情况:
- a即等于1,也等于2,还等于3。(快滚吧不会有这么不正经的a存在)
- a不等于1,也不等于2,还不等于3。(好像有点意思了)
- a一会儿等于1,一会儿等于2,一会儿等于3。(那么a就是动态变化的)
我们来分析一下a在不等于 1、2、3 的同时还要是动态变化的,那么应该怎么变? 这里面只有两个操作 ==
和 &&
, &&
是逻辑运算符,只有 ==
成立最终结果才会是 true
。那么现在的问题就是在执行 ==
的时候 a 要动态的变化,说到这儿好多人应该明白了,如果你还不明白那么把文章滑到最下面点那个红色的按钮!
先说一些前置的知识比如js的隐式转换:
js是弱类型的,变量不需要明确定义数据类型,根据不同的环境可以调整自己的类型,这个叫做隐式转换,这里的环境不只是数学运算在进行 ==
比较的时候也会进行隐式转换。在用 a 和数字进行比较的时候js会尝试把 a 转换成数字,如果 a 是一个 object
的话那会是怎么样的执行逻辑呢?
js中所有对象继承了两个转换方法 toString()
valueOf()
一般来说,对象到数字的转换过程中,js会首先尝试使用 valueOf()
方法,如果调用失败则会调用 toString()
方法。理论上我们可以覆盖对象的 toString()
valueOf()
方法来重写对象的转换,我们来尝试实现这一操作。
var a = {
valueOf: function(){
return 'valueOf'
}
}
a == 'valueOf' // true
通过重新定义对象的 valueOf
方法返回字符串 valueOf ,证实了之前的假设,那么我们现在要实现的就是让返回值变化依次加1这样才能解决上面问题,看下面的代码。
var a = {
num: 1,
valueOf: function(){
return this.num ++
}
}
console.log(a == 1 && a == 2 && a == 3) // true
答案已经给出了但是都说了是面试题,如果实现的方法只有一种还叫面试题吗?来看另外一种实现方案,看代码。
var num = 0
Object.defineProperty(window, 'a', {
get: function() {
return ++num
}
})
console.log(a == 1 && a == 2 && a == 3) // true
解释一下,js里会有一个全局的 window 对象,所有全局变量其实是挂载到 window 下面的,也就是说,如果执行 var myName = 'chuan'
那么 window.name
就是 chuan,只不过我们通常会把 window 省略掉,上面的代码对 window 下面的变量 a 做了拦截,点操作符可以理解是 get
方法。间而实现了最初的问题。
网友评论