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) :
- If two operands have different types, they are not exactly equal
- If both operands are zero
null
, then they are strictly equal - If both operands are zero
undefined
They are strictly equal - If one or both operands are
NaN
They are not exactly equal - If both operands are zero
true
Or forfalse
They are strictly equal - If both operands are
number
Type and have the same value, they are strictly equal - If both operands are
string
Type and have the same value, they are strictly equal - If both operands refer to the same object or function, they are strictly equal
- 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.
-
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.
-
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.
-
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)
- 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.
- If operands have different types:
2.1) if an operand isnull
And 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, thentrue
convert1
That will befalse
convert0
, 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 - In all the other cases above, the operands are not equal
Case 1
1 == true // true
Copy the code
The transformation steps above:
1 == true
(Using EEA rule 2.3 willtrue
convert1
)1 = = 1
Operands have the same type. Use EEA rule 1 to convert equality to congruence for comparison1 = = = 1
Both operands are numbers and have the same value. According to theIEARule 6, this is equal.)true
Case 2
'' == 0 // true
Copy the code
The transformation steps above:
' '= = 0
One operand is a string and the other is a number, according toEEA rules 2.2.' '
Is converted to a number0
)- 0 == 0(Same operand type, use EEA rule 1 to convert equality to congruence operation for comparison)
0 = = = 0
Operands of the same type have the same value, so according toThe IEA rule 6, it is an identity.true
Example 3
null == 0 // false
Copy the code
The transformation steps above:
null == 0
(null
Is the primitive type, and 0 isnumber
Type. According to theEEA rule 3)false
Example 4
null == undefined // true
Copy the code
The transformation steps above:
null == undefined
(based onEEA rules 2.1, operands are equal)true
Case 5
NaN == NaN // false
Copy the code
The transformation steps above:
NaN == NaN
(Both operands are numbers. According to theEEA rule 1, convert equality into congruence operation for comparison)NaN === NaN
(according toThe IEA rule 4, operands are strictly unequal.)false
Case 6
[''] == '' // true
Copy the code
The transformation steps above:
["] = = ' '
([...]
It’s an array sum' '
It’s a string. applicationEEA rules 2.4And useOPCA rule 2
Converts the array to its original value' '
)'a' = = ' '
(Both operands are strings, convert equality to congruence for comparison)= = = ' ' ' '
The operands are of the same type and have the same value. useThe IEA rule 7, they are equal.)true
Example 7
{} == true // false
Copy the code
The transformation steps above:
{} == true
(using theEEA rules 2.3That will betrue
The operand is converted to1
){} = = 1
The first operand is an object, so it is necessaryOPCAConvert it to the original value)"[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)NaN == 1
Both operands are numbers, so useEEA rule 1Convert equality to congruence for comparison)NaN === 1
(according toThe IEA rule 4, what is nothing to do withNaN
That’s the same thingfalse
)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