Implementation: (a == 1 && a == 2 && a == 3) === true

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:

  1. Converts two compared values ​​to the same type
  2. 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
insert image description here
points of information that can be obtained from the table (a == 1).a

  1. a is of type Stringand is convertible to a number1('1' == 1 => true)
  2. a is of type Booleanand is convertible to a number1 (true == 1 => true)
  3. 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:

  1. If there is a Symbol.toPrimitivemethod, call it first and then return, otherwise go to 2.
  2. Call valueOf, if convertible to primitive type, return, otherwise do 3.
  3. Call toString, return if convertible to primitive type, otherwise do 4.
  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 valueOfandtoString

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 windowread .a_a

Object.defineProperty(window, 'a', {
    
    
	get() {
    
    
		return _a++;
	}
})

If you can think of it, definePropertyyou 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?

Guess you like

Origin blog.csdn.net/weixin_44761091/article/details/123891194