经典面试题:让 a == 1 && a == 2 && a == 3 成立

语言: CN / TW / HK

一、问题解析

JavaScript if (a == 1 && a == 2 && a == 3) { console.log('Win') }

如何打印除Win?

看到题目的第一眼,我是蒙蔽的.怎么可能会有如此矛盾的情况发生呢?就相当于一个人怎么可能即是小孩,又是成年人,还是老年人呢?

冷静下来,发现一些端倪。

它没说让a同时等于1 2 3。

而且js是单线程运行的。 即使它们写在了一行,那也是从左到右执行的. 所以它们从时空上面就不是同一时期的东西。

既然不是同一时期的东西,那么一个人当然可以是可以成为小孩子,之后成为过成年人,然后变成老年人了。

回到题目,那么我想要让这个条件成立,就需要获取一次a的同时,让它自增1。

二、解决办法

2.1 toString

第一种方法,利用判断过程中的[隐式转换]的toString方法。在我的另外一篇为什么[] == ![]结果为true?中详细阐述过。

```js const a = { _a: 0, toString: function() { return ++_a } }

```

运行一次,就给_a加1,然后返回.

因为toString是Object.prototype上面默认的方法,所以这个办法相当于把正常的隐式转换中toString 方法给拦截了。

涉及原型和原型链的知识点

问题是可以解决了,但是带来了新的问题.如果题目把双等变成三个等怎么办。这里的toString 已经默认把对象转化为字符串了.使用toStirng的话,结果就不成立了.

2.2 defineProperties

使用对象的数据拦截法:

JavaScript Object.defineProperties(window, { _a: { value: 0, writable: true }, a: { get: function() { return ++_a } } })

涉及到对象的访问器相关内容

不知道是否让你想起ue中的watch或者computed的指令呢?

三、总结

是否会做这道面试题没有任何意义。但是能够了解到这个面试题包含的知识点就很有意思。

从隐式类型转换到原型和原型链,最后到对象的访问权属性。如果要继续延伸的话,Vue的双向绑定的实现原理,class中static的实现等等。

这些就是为什么说,要构建前端的知识体系,能够从一个知识点延伸到相关的其他知识点。

“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 7 天,点击查看活动详情