分享一道有趣的题
本文最后更新于:2020年3月22日 晚上
今天在群里看到朋友发了一道有趣的题
就是如何让(a == 1 && a == 2 && a == 3) === true
这个等式成立。一开始看到这个题觉得是无稽之谈,这不扯淡吗,一个变量能同时满足几个值?但是朋友这么问还真说不定有可能,于是开始一波思考。
首先分析一下等式左边的a==1
,a==2
,a==3
,相等符号==
会判断两个变量的值是否相等,如果不相等,则会触发变量类型的隐式转换;全等符号===
则同时判断变量的值和类型,其中一个不相等,判断结果为false
。
然后我们假设等式已经成立,既然这个等式能够成立,那么变量a
肯定不是一个普通的变量,至少基本数据类型满足不了这种骚操作,那么它应该是复杂数据类型。
接着,对象跟基本数据类型做对比或运算的时候,会有我们上面说的类型隐式转换的一个过程,这里分三种情况:
- 对象转换的规则,会先调用内置的
[ToPrimitive]
函数,如果部署了Symbol.toPrimitive
方法,优先调用再返回; - 调用
valueOf()
,如果转换为基础类型,则返回; - 调用
toString()
,如果转换为基础类型,则返回;
如果上面几种情况都没有返回基础类型,就会报错。
那么分析到这里就很简单了,重写其中某个方法,覆盖默认行为:
我们分别给对象a
重写覆盖了 Symbol.toPrimitive
、valueOf
和toString
方法,以方便我们调试。从控制台的输出可以看到,对象在判断转换过程中,会分别触发上述的方法,并且可以看到等式已经成立!
这说明确实可以存在这种“不可思议”的情况。不过现实中不建议这样去改变对象的默认行为,往往会导致不可预料的后果。但是不可否认,这种骚操作的题,一定程度上可以反馈出我们对JS基础、底层操作的理解和积累。学习一途,真的是任重而道远啊~
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!