如何让表达式(a ==1 && a== 2 && a==3)等于true?

点击右上方红色按钮关注“小郑搞码事”,每天都能学到知识,搞懂一个问题!

突然看到这一个这样的问题,感觉这个问题比较有意思,看似一道毫无"价值"的题(因为我在日常工作代码中从来不写这样的代码),但是,通过分析这道题,确实也能顺便复习几个基础知识点和JS的执行机制。

这道题解决的关键点有可能是因为它用的是相等符(==),而不是全等符(===,全等的关键是数据类型也得一样)。想了一下,有以下几个解决方案的思路还是很容易想到的。

第一种方案:利用对象返回

我们可以创建一个带有自定义valueOf方法(或者toString方法)函数的对象,每次使用时,改变它的返回值。如下代码:

如何让表达式(a ==1 && a== 2 && a==3)等于true?

上面代码输出:小郑搞码!

为什么会输出:小郑搞码!?在if条件判断中,我们使用的是相等符(==),相等符比较的目标操作数类型可以不同,所以在比较的时候,如果其中一个操作数与另一个类型不同,则 JS 引擎会尝试将一个操作转换为另一个类型。

就上面我写的这段代码而言,两个比较操作符,右边是数字,左边是一个对象的情况下,会将对象转换成一个数,对象转成成数的方式就是,对象会去调用它的valueOf方法(valueOf是可以调用的),若valueOf不可调用则会自动调用toString方法得到一个字符串,然后,JS引擎在尝试将字符串转成数字进行比较。

上面if条件判断代码中,每判断一次,a的值会自动加1。所以判断a等于1,2,3,4......与运算后都会返回true。有疑问者,可以自行运行代码验证一下。

第二种方案:ECMAScript解释空格为标识符

这第二个方案,就得记住了,因为它简单好理解,但一般人不容易想到。

来看一段代码:

如何让表达式(a ==1 && a== 2 && a==3)等于true?

上面这段代码输出:true。

请注意,第一个a变量后面那个奇怪的间距。你可以认为它是一个普通的空格,从上面代码输出结果看,ECMAScript不会将其解释为一个空格。这就意味着它是一个有效的标识符。因此,上面是两个完全不同的变量。就好比将空格换成一个下划线。

如何让表达式(a ==1 && a== 2 && a==3)等于true?

输出:true。

知道这一点后,现在,我们来解决一下题目的问题。

如何让表达式(a ==1 && a== 2 && a==3)等于true?

输出:小郑搞码!

第三种方案:JavaScript对象劫持

使用对象劫持,关于JavaScript对象劫持想了解更多的,可以翻一下之前我写的文章。这里,来看一下,使用对象劫持怎么解决题目中的问题。

如何让表达式(a ==1 && a== 2 && a==3)等于true?

使用一个get方法,让 a 的返回值为三个不同的值,这个逻辑思路有点类似于第一种方案,也很好理解,在实际项目代码中,并不推荐这么搞。

最后总结一下:

对于方案一,其实主要是利用了相等的原理,需要注意对象的比较情况。

对于方案二,像是一种障眼法,本质上还是和题目有些差别的。

对于方案三,利用JS劫持,改变了get方法。这种方式对于全等也是有效的。


分享到:


相關文章: