一道不正经的前端面试题

请...听...题...

如何让 a == 1 && a == 2 && a == 3 的运行结果是true ?

如果此时你的表情是


一道不正经的前端面试题_第1张图片

那你可以把这边文章X掉安心搬砖了

如果你的表情是


一道不正经的前端面试题_第2张图片

那你可得认真看下去

我们来分析一下,若想 a == 1 && a == 2 && a == 3 成立无非三种情况:

  1. a即等于1,也等于2,还等于3。(快滚吧不会有这么不正经的a存在)
  2. a不等于1,也不等于2,还不等于3。(好像有点意思了)
  3. a一会儿等于1,一会儿等于2,一会儿等于3。(那么a就是动态变化的)

我们来分析一下a在不等于 1、2、3 的同时还要是动态变化的,那么应该怎么变? 这里面只有两个操作 ==&&, && 是逻辑运算符,只有 == 成立最终结果才会是 true 。那么现在的问题就是在执行 == 的时候 a 要动态的变化,说到这儿好多人应该明白了,如果你还不明白那么把文章滑到最下面点那个红色的按钮!

一道不正经的前端面试题_第3张图片

先说一些前置的知识比如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 方法。间而实现了最初的问题。

你可能感兴趣的:(一道不正经的前端面试题)