① According to the operator priority,! The priority of the command is greater than ==, so it is executed first! []! Variables can be converted to Boolean type, null, undefined, NaN, and empty string (“) are true, the rest are false. So! [] ==! [] equals [] == false

If one of the operands is a Boolean, convert it to a value before comparing equality — false to 0, and true to 1. [] is equivalent to [] == false is equivalent to [] == 0

If one operand is an object and the other is not, then valueOf() is called. If the object has no valueOf() method, then toString() is called. [] the toString () – > ‘is an empty string (return), that is, [] = = 0 is equivalent to’ = = 0

If one of the operands is a string and the other is a value, convert the string to a value before comparing equality. If one of the operands is a string, convert the string to a value before comparing equality

To sum up:

[] == ! [] -> [] == false -> [] == 0 -> ” == 0 -> 0 == 0 -> true

So for {} ==! The same goes for {}. The key is that {}.toString() -> NaN(returns NaN). The equality operator returns false if one of the operands is NaN: {} ==! {} -> {} == false -> {} == 0 -> NaN == 0 -> false