前几天闲着无聊,玩手机无意中发现一个题,觉得挺有意思的,就顺手记录一下:
题目:
a==1&&a==2&&a==3 === true
思考:我思考了一会,这让一个值既是1又是2又是3的,不可能吧,这肯定是一个伪命题,但突然我灵光一现,对象属性不是可以拦截吗,我能不能在这上面做文章,于是就有了接下来的代码
第一种,对象字面量属性修改
var a = {
value: 0,
valueOf: function() {
this.value++;
return this.value;
}
};
// 或
let a = {
i: 1,
toString: function () {
return this.i++
},
};
第二种修改对象原型上的toString方法
let a = {
value: 1,
};
a.__proto__.toString = function () {
return this.value++;
};
第三种 对象代理
let a = new Proxy({value:1},{
get:function(target){
const bbb = target.value++
return ()=>bbb;//这里一定要定义成一个方法 因为 a == 1 在进行比较的时候 会先进行类型的转化 因为a是一个对象 所以会先调用对象的valueOf方法或是toString方法 所以这里返回一定要是一个函数
}
})
第四种 Object.defineProperty()
let a = {}
let b = 1
Object.defineProperty(a,'value',{
configurable: true,
get(){
return b++
}
})
// 或
var value = 1;
Object.defineProperty(globalThis, 'a', {
get: function() {
return value++;
},
configurable: true
});
// 这里要注意的是 globalThis 代表的是全局的this值,类似于全局对象 Window
以上4中都是可以满足条件需求,第四种中的第一种是以对象的形式来进行展示的
除去以上方法外,ChartGpt另外还给了几种方案
方案1:重写数组的toString方法
var a = [1, 2, 3];
a.toString = function() {
return this.shift();
};
console.log(a == 1 && a == 2 && a == 3); // 输出 true
方案2:使用闭包
var a = (function() {
var value = 0;
return function() {
return value++;
};
})();
console.log(a() == 1 && a() == 2 && a() == 3); // 输出 true
方案3:Symbol.toPrimitive
var a = {
[Symbol.toPrimitive](hint) {
if (hint === 'number') {
if (!this.value) {
this.value = 1;
} else {
this.value++;
}
return this.value;
}
}
};
console.log(a == 1 && a == 2 && a == 3); // 输出 true
以上就是我所想到的所有方法,有别的方法的也欢迎大家进行补充