preface

Before ESLint, my code formatting was pretty much what I wanted to do. Since introducing ESLint on a Vue project three years ago, my code has become so normative that I am now obsessive-compulsive. Eslint has a lot of code specification standards in it. In general, the React project code follows the Airbnb specification and the Vue project code follows the standard specification. There is one fine print: always use === instead of ==. So I’ve stuck with this habit to this day, but I didn’t dig into it, except that it reduces the number of unexpected errors in the code. Since I myself am not content with “knowing what it is and not knowing why,” I want to delve into the difference between === and ===.

The difference between === and ==

The essential difference between === and == is that the former determines whether the operands on both sides of the operator are strictly equal, and does not perform any data type conversion. The latter determines whether the operands on either side of the operator are not strictly equal, and implicit type conversions are performed appropriately.

== Instructions for use

Here are the implicit conversions of the operands x and y when compared with the == operator:

1.xwithyThe same type

1.1 If x is undefined, true is returned.

console.log(undefined= =undefined); // true
Copy the code

1.2 If x is null, true is returned.

console.log(null= =null); // true
Copy the code

1.3 If x is number and either x or y is NaN, false is returned. (NaN is not equal to itself)

console.log(NaN= =0); // false
console.log(0= =NaN); // false
console.log(NaN= =1); // false
console.log(1= =NaN); // false
console.log(NaN= =NaN); // false
Copy the code

1.4 If x is number and the values of x and y are the same, true is returned. Return false if the values of x and y are not equal.

console.log(0= =0); // true
console.log(1= =1); // true
console.log(0= =1); // false
Copy the code

1.5 If x is of type number and the value of x and y is +0 or -0, true is returned.

console.log(0= = +0); // true
console.log(+0= =0); // true
console.log(+0= = +0); // true
console.log(0= =0); // true
Copy the code

1.6 If x is a string, true is returned if and only if the x and Y character sequences are exactly the same. Otherwise, return false.

console.log('foo'= ='foo'); //true
console.log('foo'= ='bar'); // false
Copy the code

1.7 If x is Boolean, true is returned when both x and y are true or false. Otherwise, return false.

console.log(true= =true); // true
console.log(false= =false); // true
console.log(true= =false); // false
console.log(false= =true); // false
Copy the code

1.8 If x is of type object, true is returned if and only if x and y are the same reference. Otherwise, return false.

var x = {}, y = {}, z = x;
console.log(x == y); // false
console.log(x == z); // true
console.log(y == z); // false
console.log(x == {}); // false
console.log({} == y); // false
console.log({} == {}); // false
Copy the code

2.xwithyDifferent types

2.1 Return true if x is null and y is undefined, or x is undefined and y is null.

console.log(null= =undefined); // true
console.log(undefined= =null); // true
Copy the code

2.2 If x and y are of the type number and the other is of the type string, the string type is implicitly converted to the number type before numerical comparison.

console.log('123'= =123); // true <=> Number('123') == 123 <=> 123 == 123
console.log(123= ='123'); // true <=> 123 == Number('123') <=> 123 == 123
console.log('abc'= =123) // false <=> Number('abc') == 123 <=> NaN == 123
Copy the code

2.3 If either x or Y is of Boolean type, the Boolean type is implicitly converted to number type before numerical comparison.

console.log(false= =0); // true <=> Number(false) == 0 <=> 0 == 0
console.log(true= =1); // true <=> Number(true) == 1 <=> 1 == 1
console.log(false= =2); // false <=> Number(false) == 2 <=> 0 == 2
console.log(true= =2); // false <=> Number(true) == 2 <=> 1 == 2
Copy the code

2.4 If x and y are number, String, or Boolean, and the other is object, object implicitly invokes valueOf or toString for comparison.

var foo = { bar: 0 };
console.log(foo == 2); // false <=> foo.toString() == 2 <=> '[object Object]' == 2 <=> Number('[object Object]') == 2 <=> NaN == 2
console.log(foo == '2'); // false <=> foo.toString() == '2' <=> '[object Object]' == '2'
console.log(foo == '[object Object]'); // true
Copy the code

Ps: We can override valueOf or toString methods to override the default behavior of native methods for best comparison.

var foo = { bar: 0 };
foo.toString = (a)= > '2'; // foo.valueOf = () => 2; If both are overwritten, valueOf prevails
console.log(foo == 2); // true;
console.log(foo == '2'); // true
Copy the code

2.5 In other cases, return false.

console.log('123abc'= =123); // false
console.log(null= =false); // false
console.log(undefined= =false); // false.Copy the code

Next, let’s explore an interesting topic: [] ==! [] // -> true, using the above detailed rules, we deduce step by step.

/ /! [] Returns a Boolean type ->! Boolean([]) -> ! true -> false[] = =! [] < = > [] = =false
/ / the object types and Boolean comparison, first convert object - > [] - > [] the toString () - > '[] = =false< = >' '= =false
Boolean -> false -> Number(false) -> 0
' '= =false< = >' '= =0
String () -> number ('') -> 0
' '= =0< = >0= =0
// So the final result is true.
Copy the code

As you can see, these details are hard enough to remember, and if we don’t pay attention to how to use ==, there will be many unexpected bugs in the program. In order to avoid errors, I usually only use ===, not ==, in actual development.

=== Instructions for use

Now, let’s look at the specification for using === =, again x and y for the operands on both sides of the operator.

  • If x and y are of different types, return false.
console.log(undefined= = =null); // false
console.log(1= = =true); // false
console.log(0= = =false); // false
console.log(1= = ='1'); // false
console.log(0= = ='0'); // false
console.log('1'= = =true); // false
console.log('0'= = =false); // false
console.log(0= = = []);// false
console.log(false= = = []);// false
console.log(' '= = = []);// false
Copy the code
  • If x and y are of the same type, and if they are both basic types, compare whether they are equal. If it is a reference, check whether the reference address is the same as the reference address.
var a = {}, b = {}, c = a;
console.log(undefined= = =undefined); // true
console.log(null= = =null); // true
console.log(0= = =0); // true
console.log(0= = =1); // false
console.log('0'= = ='0'); // true
console.log('0'= = ='1'); false
console.log(false= = =false); // true;
console.log(true= = =false); // false
console.log({} === {}); // false
console.log(a === b); // false
console.log(a === c); // true;
console.log(b === c); // false.Copy the code

As you can see, using === has only two rules and doesn’t involve any implicit conversions at all, greatly improving the debuggability and predictability of the code and making it much easier to use than ==. So, in everyday development, I highly recommend using === and using == as little as possible. Perhaps my recommendation is not authoritative, but this specification is already written into many JavaScript code specifications.