A little-known JS problem: [] == ![] is true, but {} == !{} is false

A little-known JS problem: [] == ![] is true, but {} == !{} is false
console.log( [] == ![] ) // true
console.log( {} == !{} ) // false

When comparing strings, numbers, and Boolean values ​​for equality, the problem is relatively simple. But when it comes to comparing objects, the problem becomes complicated. The original equality and inequality operators in ECMAScript converted objects to similar types before performing the comparison. Later, some people questioned whether this conversion was reasonable. Finally, ECMAScript's solution is to provide two sets of operators:

Equality and inequality - convert first, then compare (==)
Congruent and Not Congruent - Compare without Conversion (===)

The equality operator in ECMAScript is represented by two equal signs (==). If the two operands are equal, it returns true. This operator will first convert the operands (usually called forced conversion) and then compare their equality.

When converting different data types, for equality and inequality operators: the following basic conversion rules are given in the book JS Elevation

① If one operand is a Boolean value, it is converted to a numeric value before comparing for equality—false is converted to 0 and true is converted to 1;

② If one operand is a string and the other operand is a number, convert the string to a number before comparing for equality

③. If one operand is an object and the other is not, call the object's valueOf() method and use the obtained primitive type value to compare according to the previous rules.

These two operators follow the following rules when performing comparisons.

①, null and undefined are equal

② Before comparing for equality, null and undefined cannot be converted to any other value

③. If one operand is NaN, the equality operator returns false, while the inequality operator returns true. Important: Even if both operands are NaN, the equality operator returns false because, by rule, NaN is not equal to NaN.

④. If both operands are objects, compare whether they are the same object. If both operands point to the same object, the equality operator returns true; otherwise, it returns false

Here is a digression: [] and {} are both reference types, which are stored in the heap memory, and in the stack memory there will be one or more addresses pointing to the data corresponding to this heap memory. So when using the == operator, for reference type data, what is compared is the address, not the actual value.

Now let's discuss why the result of [] == ! [] is true

①. According to the operator priority, ! The priority of is greater than ==, so it will be executed first![]

! Variables can be converted to boolean type. The negation of null, undefined, NaN, and empty string ('') is true, and the rest are false.

So! The result after [] operation is false

That is, [] == ! [] is equivalent to [] == false

② According to the rules mentioned above (if one operand is a Boolean value, it is converted to a numeric value before comparing equality - false is converted to 0 and true is converted to 1), you need to convert false to 0

That is, [] == ! [] is equivalent to [] == false, which is equivalent to [] == 0.

③. According to the rules mentioned above (if one operand is an object and the other operand is not, the object's valueOf() method is called, and the obtained primitive type value is compared according to the previous rules. If the object does not have a valueOf() method, toString() is called)

For an empty array, [].toString() -> '' (returns an empty string)

That is, [] == 0 is equivalent to '' == 0

④ According to the rules mentioned above (if one operand is a string and the other operand is a number, the string is converted to a number before comparing equality)

Number('') -> returns 0

This is equivalent to 0 == 0, which naturally returns true.

To summarize:

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

The same is true for {} == !{}

The key is {}.toString() -> NaN (returns NaN)

According to the above rules (if one operand is NaN, the equality operator returns false)

To summarize:

{} == ! {} -> {} == false -> {} == 0 -> NaN == 0 -> false

Then I believe that everyone can easily answer the following two questions.

console.log( [] == !{} ) // true
console.log( {} == ![] ) // false

Summarize

This concludes this article about the little-known JS issue that [] == ![] evaluates to true, while {} == !{} evaluates to false. For more information about JS [] == ![] evaluating to true, please search previous articles on 123WORDPRESS.COM or continue browsing the following related articles. I hope you will support 123WORDPRESS.COM in the future!

<<:  mysql5.7.22 download process diagram

>>:  How to delete folders, files, and decompress commands on Linux servers

Recommend

A brief discussion on the definition and precautions of H tags

Judging from the results, there is no fixed patte...

Detailed installation steps for MySQL 8.0.11

This article shares the installation steps of MyS...

Detailed explanation of the process of building and running Docker containers

Simply pull the image, create a container and run...

HTML basics - CSS style sheets, style attributes, format and layout details

1. position : fixed Locked position (relative to ...

A record of the pitfalls of the WeChat applet component life cycle

The component lifecycle is usually where our busi...

How to deploy springcloud project with Docker

Table of contents Docker image download Start mys...

Windows 2016 Server Security Settings

Table of contents System update configuration Cha...

Practice of multi-layer nested display of element table

There is a requirement for a list containing mult...

2 reasons why html-css tag style setting does not work

1 CSS style without semicolon ";" 2 Tags...

WeChat applet implements a simple calculator

A simple calculator written in WeChat applet for ...

Understanding and using React useEffect

Table of contents Avoid repetitive rendering loop...

Div nested html without iframe

Recently, when doing homework, I needed to nest a ...

Detailed explanation of deploying MySQL using Docker (data persistence)

This article briefly describes how to use Docker ...

Vue2.0 implements adaptive resolution

This article shares the specific code of Vue2.0 t...

CSS realizes process navigation effect (three methods)

CSS realizes the process navigation effect. The s...