如何使 (a == 1 && a == 2 && a == 3) 成立?
题干
js
(a == 1 && a == 2 && a == 3) // ?
- 对象原始值转换
题解
利用
obj[Symbol.toPrimitive](hint)
方法,使其每次返回不同的值。利用
==
运算符会进行隐式类型转换的特性,重写对象的toString
或valueOf
方法,使其每次返回不同的值。利用
Object.defineProperty
方法劫持,定义一个get
函数,使其每次返回不同的值。
🌰:
js
// 方法一
let a = { value: 0 }
a.toString = function() {
return this.value += 1;
}
console.log(a == 1 && a == 2 && a == 3); // true
// 方法二
let a = [1,2,3];
a.toString = a.shift;
console.log(a == 1 && a == 2 && a == 3); // true
// 方法三
let a = { value: 0 }
a.valueof = function(){
return this.value += 1;
}
console.log(a == 1 && a == 2 && a == 3); // true
// 方法四
Object.defineProperty(window,'a',{
get:function() {
this.value ? this.value++ : this.value = 1;
return this.value;
}
})
console.log(a == 1 && a == 2 && a == 3); // true
// 方法五
let a = { value: 0 }
a[Symbol.toPrimitive] = function(hint) {
console.log(hint); // default
return this.value += 1;
}
console.log(a == 1 && a == 2 && a == 3); // true
对象原始值转换步骤:
对象原始值转换时,JS
会尝试查找并调用三个对象方法:
调用
obj[Symbol.toPrimitive](hint)
—— 带有symbol
键Symbol.toPrimitive
(系统symbol
)的方法,如果这个方法存在的话。否则,如果
hint
是"string"
—— 尝试调用obj.toString()
或obj.valueOf()
,无论哪个存在。否则,如果
hint
是"number"
或"default"
—— 尝试调用obj.valueOf()
或obj.toString()
,无论哪个存在。
详见 现代JavaScript - 对象原始值转换 一节。