面试题 - 如何让 (a == 1 && a == 2 && a==3) 结果为 true

面试题 - 如何让 a == 1 && a == 2 && a==3 结果为 true

面试题

如何让一个变量 a = = 1 && a = = 2 && a = = 3 结果为 true。

考察点

此题考察的是隐式类型转换。想要变量 a 等于 (==)1/2/3 ,那么变量 a 不可能是基本数据类型。所以只能是引用数据类型。引用数据类型与基本数据类型进行比较时,会隐式地调用 toString 方法,将其转换为基本数据类型。

方法一

数组模式下,重写 toString 方法或者 join 方法。

 var a = [1,2,3];
 a.toString = a.shift;
 console.log(a == 1 && a == 2 && a == 3) //true
 var a = [1,2,3];
 a.join = a.shift;
 console.log(a == 1 && a == 2 && a == 3) //true

方法二

通过 definePropertyProxyget 方法进行数据劫持。

 Object.defineProperty(window, 'a', {
  get: function() {
        return this.value = this.value ? (++this.value) : 1
     }
 });
 console.log(a == 1 && a == 2 && a == 3) //true
let i = 1;
var a = new Proxy({},{
     get:function () {
         return ()=>i++
     }
 })
 console.log(a == 1 && a == 2 && a == 3) //true

这里需要注意的是 defineProperty 和 Proxy 的参数区别。defineProperty 的 get 方法在第三个参数对象中,return 的是 value(值)。而 Proxy 的 get 方法在第二个参数对象中,return 的是 function (函数)。

方法三

重写对象的 toString 方法或者 valueOf 方法。

var a = {
     num:1,
     toString:function () {
         return this.num++
     }
 }
console.log(a == 1 && a == 2 && a == 3) //true
var a = {
     num:1,
     valueOf:function () {
         return this.num++
     }
 }
console.log(a == 1 && a == 2 && a == 3) //true

方法四

部署 ES6 Symbol 的 toPrimitive 接口。

var a = {
     num: 1,
     [Symbol.toPrimitive]() {
         return this.num++;
     }
 }
console.log(a == 1 && a == 2 && a == 3) //true

总结

  1. 数组,重写 toString 方法或者 join 方法。join 方法默认调用 toString 方法。
  2. 对象,重写 toString 方法或者 valueOf 方法。或者部署 ES6 [Symbol.toPrimitive] 接口。或者通过 defineProperty/Proxy 的 get 方法进行数据劫持。
发布了280 篇原创文章 · 获赞 2497 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/weixin_44135121/article/details/104721841