Article directory
foreword
There are tricky solutions to this question, but when asked this question, what the interviewer really wants to examine is your understanding of the knowledge point of implicit conversion , and whether you can consider data hijacking
tricky solution
let i=1;
with({
get a() {
return i++;
}
}){
if(a==1 && a==2 && a==3) {
console.log('哈哈哈,成功了');
}
}
implicit conversion
==
When comparing two values in js, the following operations are performed:
- Converts two compared values to the same type
- After conversion (one or both sides of the equation may be converted), the comparison of the values is performed
The final comparison method is equivalent to ===
the comparison method of the equality operator, and the equality operator satisfies the commutative law.
The equality operator compares values of different types as shown in the following figure: There are several
points of information that can be obtained from the table (a == 1)
.a
- a is of type
String
and is convertible to a number1('1' == 1 => true)
- a is of type
Boolean
and is convertible to a number1 (true == 1 => true)
- The type of a is
Object
, after passing through the conversion mechanism, can be converted to the number 1 (see below)
There is nothing special about the "conversion mechanism"
rules 1 and 2 of the object to the original type, let's look at 3: the object is converted to the original type, and the built-in [ToPrimitive]
function will be called. The logic is roughly as follows:
- If there is a
Symbol.toPrimitive
method, call it first and then return, otherwise go to 2. - Call
valueOf
, if convertible to primitive type, return, otherwise do 3. - Call
toString
, return if convertible to primitive type, otherwise do 4. - If neither returns the original type, an error will be reported.
solution:
const a = {
i: 1,
[Symbol.toPrimitive]() {
return this.i++
}
}
// 每次进行a == xxx时都会先经过Symbol.toPrimitive函数,自然也就可以实现a依次递增的效果
if (a == 1 && a == 2 && a == 3) {
console.log('哈哈哈,成功了')
}
Of course you can also use valueOf
andtoString
const a = {
i: 1,
valueOf() {
return this.i++
}
}
// 每次进行a == xxx时都会先经过valueOf/toString函数,自然也就可以实现a依次递增的效果
if (a == 1 && a == 2 && a == 3) {
console.log('哈哈哈,成功了')
}
data hijacking
Object.defineProperty
, by hijacking the object and incrementing by 1 each time a property is window
read .a
_a
Object.defineProperty(window, 'a', {
get() {
return _a++;
}
})
If you can think of it, defineProperty
you will naturally think of itproxy
let a = new Proxy({
i:1}, {
get(target){
console.log(target);
return () => target.i++
}
})
Three ways, have you learned it?