By Dmitri Pavlutin

Translator: Front-end wisdom

Source: dmitripavlutin

The more you know, the more you don’t know

Like it and see. Make it a habit


GitHub: github.com/qq449245884… Has included more categories of previous articles, as well as a lot of my documentation and tutorial material. Welcome Star and Perfect, you can refer to the examination points for review in the interview, I hope we can have something together.

In everyday JS coding, it can be difficult to see how the equality operator (==) works. Especially when operands have different types. This can sometimes produce hard-to-recognize bugs in conditional statements. It is easy to see why 0 == 8 is flase or ” == false is true. But it’s not clear why {} == true is false. We’re going to talk about how fat this is.

Before we get to that, a few terms:

  • The Operator represents the symbol of an operation. For example, the equality operator == compares two values, the equality operator === compares two values and their types, and the addition operator + two numbers and or concatenates two strings.

  • Operand is the body of an operation. It is the number of operations performed. For example, in the expression 0 == {}, 0 is the first operand and {} is the second operand.

  • The basic data types (primitives) in JS include number, string, Boolean, NULL, undefined, and symbol.

The congruent operator ===

Congruent and incongruent operators follow the following basic rules (IEA rules) :

  1. If two operands have different types, they are not exactly equal
  2. If both operands are zeronull, then they are strictly equal
  3. If both operands are zeroundefinedThey are strictly equal
  4. If one or both operands areNaNThey are not exactly equal
  5. If both operands are zerotrueOr forfalseThey are strictly equal
  6. If both operands arenumberType and have the same value, they are strictly equal
  7. If both operands arestringType and have the same value, they are strictly equal
  8. If both operands refer to the same object or function, they are strictly equal
  9. In all of these other cases the numbers are not exactly equal.

The rules are simple.

It is worth mentioning that NaN results in false when compared to any other value in congruent operations. Let’s look at some examples. It’s a good way to learn these rules.

Case 1

1 === "1" // false, rule 1Copy the code

Operands are different types (numbers and strings), and they are not equal based on IEA rule 1.

Case 2

0 === 0 // true, rule 6Copy the code

Operands have the same type and the same value, so they are strictly equal according to IEA rule 6.

Example 3

Undefined === undefined // true, rule 3Copy the code

Both operands are undefined and, applying IEA rule 3, they are equal.

Example 4

Undefined === null // false, rule 1Copy the code

Because operands are different types, they are not the same according to IEA rule 1.

Case 5

NaN === NaN // false, IEA Rule 5Copy the code

Operands are of the same type, but IEA rule 4 states that any comparison with NaN is not equal.

Case 6

var firstObject = {}, secondObject = firstObject; secondObject['name'] = 'Neo'; SecondObject === firstObject // true, IEA rule 8Copy the code

The two variables firstObject and secondObject are references to the same object and are equal according to IEA rule 8.

Example 7

[] === [] //false, IEA Rule 9Copy the code

The literal [] creates a new array reference. These two operands are of the same type (object), but they refer to different objects. According to IEA rule 9, they are not equal.

Rules for converting an object to its original value

Object to a Boolean value

The object-to-boolean conversion is simple: all objects (including numbers and functions) are converted to true. The same is true for wrapped objects: New Boolean(false) is an object rather than a primitive value, which will be converted to true.

Object to string

Both object-to-string and object-to-number conversions are done by calling a method on the object to be converted. One troublesome fact is that JS objects have two different methods for performing transformations, and some of the special scenarios discussed next are more complex. It is worth noting that the conversion rules for strings and objects mentioned here only apply to native objects. Host objects (such as those defined by a Web browser) can be converted to strings and numbers according to their respective algorithms.

All objects inherit two conversion methods. The first is toString(), which returns a string that reflects the object. The default toString() method does not return an interesting value:

({x:1,y:2}).toString()  //=>"[object object]"
Copy the code

Many classes define more specific versions of toString() methods. For example, the toString() method of an array converts each array element to a string, adding commas between the elements and merging them into a result string.

The toString() method of the function returns the implementation definition of the function. In fact, the implementation here is usually to convert user-defined functions to JS source strings.

The toString() method for Date returns a readable Date and time string.

The toString() method of RegExp converts the RegExp object to a string representing the regular expression’s immediate quantity:

A few examples:

[1, 2, 3]. The toString () / / = > "1, 2, 3" (function (x) {f (x); }).toString() // => "function(x){ f(x); } "/ \ d + / g.t oString () / / = >" / \ d + / g "new Date (2019,9,16). The toString () / / = >" Wed Oct 16, 2019 00:00:00 GMT + 0800 (China standard time)"Copy the code

Another function that converts objects is valueOf(). If any original value exists, it defaults to converting the object to the original value that represents it. Objects are compound values, and most objects can’t really be represented as a raw value, so the default valueOf() method simply returns the object itself, rather than returning a raw value. Arrays, functions, and regular expressions simply inherit this method, and the valueOf() method that calls instances of these types simply returns the object itself. The valueOf() method of the Date returns an internal representation of it: the number of milliseconds since January 1, 1970.

New Date (2019,9,16). The valueOf () / / 1571155200000Copy the code

Object-to-string and object-to-number conversions are done using the toString() and valueOf() methods. It is important to note, however, that in some special scenarios JS performs a completely different object-to-original conversion.

JS object to string conversion through the following steps, we refer to the OPCA algorithm.

  1. If the method valueOf() exists, it is called. If valueOf() returns a raw value, JS converts the value to a string (if it isn’t a string itself) and returns the string result.

  2. The toString() method is called if it exists. If toString() returns a raw value, JS converts the value to a string (if it is not a string itself) and returns the string result. Note the conversion of raw values to strings.

  3. Otherwise, JS cannot get a raw value from toString() or valueOf(), which will throw a TypeError: cannot convert an object to a raw value exception

Most native objects return the object itself when the valueOf() method is called. So the toString() method is used more frequently.

A note about Date objects: When converted to a raw value, the object is immediately converted to a string using the toString() method. Thus, rule 1 is skipped. Ordinary JS objects, {} or new object(), are usually converted to “[object object]”.

An array is converted to by concatenating its elements with the “, “delimiter. For example [1,3, “four”] is converted to “1,3,four”.

The equality operator ==

Equality operator “==” If the two operands are not of the same type, the equality operator tries some type conversions and then compares them.

Equality Operator Algorithm (EEA)

  1. If the operands are of the same type, use the IEA above to test if they are strictly equal. If they are not strictly equal, they are not equal, otherwise they are equal.
  2. If operands have different types:

    2.1) if an operand isnullAnd the other oneundefined, then they are equal

    2.2) If one value is a number and the other is a string, the string is converted to a number first, and then the converted value is used for comparison

    2.3) If an operand is a Boolean, thentrueconvert1That will befalseconvert0, and then compare using the converted value

    2.4) if one operand is an object and the other is a number or stringOPCAThe object is converted to its original value and then compared with the converted value
  3. In all the other cases above, the operands are not equal

Case 1

1 == true // true
Copy the code

The transformation steps above:

  1. 1 == true(Using EEA rule 2.3 willtrueconvert1)
  2. 1 = = 1Operands have the same type. Use EEA rule 1 to convert equality to congruence for comparison
  3. 1 = = = 1Both operands are numbers and have the same value. According to theIEARule 6, this is equal.)
  4. true

Case 2

'' == 0 // true
Copy the code

The transformation steps above:

  1. ' '= = 0One operand is a string and the other is a number, according toEEA rules 2.2.' 'Is converted to a number0 )
  2. 0 == 0(Same operand type, use EEA rule 1 to convert equality to congruence operation for comparison)
  3. 0 = = = 0Operands of the same type have the same value, so according toThe IEA rule 6, it is an identity.
  4. true

Example 3

null == 0 // false
Copy the code

The transformation steps above:

  1. null == 0 (nullIs the primitive type, and 0 isnumberType. According to theEEA rule 3)
  2. false

Example 4

null == undefined // true
Copy the code

The transformation steps above:

  1. null == undefined(based onEEA rules 2.1, operands are equal)
  2. true

Case 5

NaN == NaN // false
Copy the code

The transformation steps above:

  1. NaN == NaN(Both operands are numbers. According to theEEA rule 1, convert equality into congruence operation for comparison)
  2. NaN === NaN(according toThe IEA rule 4, operands are strictly unequal.)
  3. false

Case 6

[''] == '' // true
Copy the code

The transformation steps above:

  1. ["] = = ' '([...]It’s an array sum' 'It’s a string. applicationEEA rules 2.4And useOPCA rule 2Converts the array to its original value' ')
  2. 'a' = = ' '(Both operands are strings, convert equality to congruence for comparison)
  3. = = = ' ' ' 'The operands are of the same type and have the same value. useThe IEA rule 7, they are equal.)
  4. true

Example 7

{} == true // false
Copy the code

The transformation steps above:

  1. {} == true(using theEEA rules 2.3That will betrueThe operand is converted to1)
  2. {} = = 1The first operand is an object, so it is necessaryOPCAConvert it to the original value)
  3. "[object object] = = 1"Because the first operand is a string and the second operand is a number, according toEEA rules 2.2"[object object]"Convert to a number)
  4. NaN == 1Both operands are numbers, so useEEA rule 1Convert equality to congruence for comparison)
  5. NaN === 1(according toThe IEA rule 4, what is nothing to do withNaNThat’s the same thingfalse)
  6. false

Practical skills

Even after going through all the examples in this article and learning the algorithms, you can see that it takes time to immediately understand complex comparisons.

Here are some tips. Bookmark this article (with Ctrl + D) and the next time you see something interesting, you can write step-by-step calculations based on the equality algorithm. If you check at least 10 examples, you won’t have any problems later.

Now try, for example [0] == 0 what are the results and conversion steps?

The equality operator == performs type conversion. As a result, unexpected results can occur, such as {}== true is false(see example 7). In most cases, it is safer to use the congruence operator ===.

conclusion

The equality and congruence operation symbol is probably one of the most commonly used operators. Understanding them is one of the steps to writing stable and less buggy JS.

The bugs that may exist after code deployment cannot be known in real time. In order to solve these bugs, I spent a lot of time on log debugging. Incidentally, I recommend a good BUG monitoring tool for youFundebug.

Original text: dmitripavlutin.com/the-legend-…

Communication (welcome to join the group, the group will give red envelopes on weekdays, interactive discussion of technology)

Dry goods series of articles summarized as follows, feel good point Star, welcome to add groups to learn from each other.

Github.com/qq449245884…

Due to space constraints, today’s share only here. If you want to know more, you can scan the TWO-DIMENSIONAL code at the bottom of each article, and then follow our wechat public number to learn more information and valuable content.

Every time I sort out my articles, I usually go to bed at 2 o ‘clock, about 4 times a week, which is very bitter. I hope to get support and give some encouragement