Comparison operator

Overview

Comparison operators are used to compare the size of two values, and then return a Boolean value indicating whether the specified conditions are met.

2 > 1; // true

The above code compares whether 2 is greater than 1 and returns true.

Note that comparison operators can compare various types of values, not just numeric values.

JavaScript provides a total of 8 comparison operators.

-> greater than operator -< less than operator -<= less than or equal to operator ->= greater than or equal to operator -== equality operator -=== strict equality operator -!= inequality operator -!== Strictly inequality operator

These eight comparison operators are divided into two categories: equality comparison and non-equal comparison. The rules of the two are different. For non-equal comparisons, the algorithm first looks at whether the two operators are both strings. If they are, then compare them in lexicographical order (in fact, compare Unicode code points); otherwise, Convert both operators to numeric values, and then compare the magnitudes of the numeric values.

Non-equal operator: string comparison

Strings are compared in lexicographic order.

"cat" > "dog"; // false
"cat" > "catalog"; // false

The JavaScript engine first compares the Unicode code point of the first character. If they are equal, compare the Unicode code point of the second character, and so on.

"cat" > "Cat"; // true'

In the above code, the lowercase c Unicode code point (99) is greater than the uppercase C Unicode code point (67), so true is returned.

Since all characters have Unicode code points, Chinese characters can also be compared.

"Big" > "small"; // false

In the above code, the Unicode code point for "big" is 22823 and "small" is 23567, so false is returned.

Non-equal operator: non-string comparison

If at least one of the two operators is not a string, it needs to be divided into the following two cases.

(1) Primitive type value

If both operators are primitive values, they are converted to numeric values ​​and then compared.

5 > "4"; // true
// equivalent to 5> Number('4')
// i.e. 5> 4

true > false; // true
// equivalent to Number(true)> Number(false)
// i.e. 1> 0

2 > true; // true
// equivalent to 2> Number(true)
// i.e. 2> 1

In the above code, both string and boolean values ​​will be converted into numerical values ​​before being compared.

Here you need to pay attention to the comparison with NaN. Any value (including NaN itself) is compared with NaN using the non-equal operator, and the result is false.

1 > NaN; // false
1 <= NaN; // false
"1" > NaN; // false
"1" <= NaN; // false
NaN > NaN; // false
NaN <= NaN; // false

(2) Object

If the operator is an object, it will be converted to a value of the original type and then compared.

To convert an object into a primitive type value, the algorithm is to first call the valueOf method; if the returned object is still an object, then call the toString method. For detailed explanation, please refer to the chapter "Data Type Conversion".

var x = [2];
x > "11"; // true
// equivalent to [2].valueOf().toString()> '11'
// i.e. '2'> '11'

x.valueOf = function () {
  return "1";
};
x > "11"; // false
// equivalent to [2].valueOf()> '11'
// i.e. '1'> '11'

The same is true for comparisons between two objects.

[2]> [1] // true
// equivalent to [2].valueOf().toString()> [1].valueOf().toString()
// i.e. '2'> '1'

[2]> [11] // true
// equivalent to [2].valueOf().toString()> [11].valueOf().toString()
// i.e. '2'> '11'

{x: 2} >= {x: 1} // true
// equivalent to {x: 2 }.valueOf().toString() >= {x: 1 }.valueOf().toString()
// i.e.'[object Object]' >='[object Object]'

Strict equality operator

JavaScript provides two equality operators: == and ===.

Simply put, the difference between them is that the equality operator (==) compares whether two values ​​are equal, and the strict equality operator (===) compares whether they are the "same value". If the two values ​​are not of the same type, the strict equality operator (===) directly returns false, and the equality operator (==) will convert them to the same type, and then use the strict equality operator Compare.

This section describes the algorithm of the strict equality operator.

(1) Different types of values

If the two values ​​are of different types, return false directly.

1 === "1"; // false
true === "true"; // false

The above code compares the value 1 with the string "1", and the boolean true with the string "true". Because of the different types, the results are all false.

(2) Primitive type value of the same class

When comparing primitive values ​​(numeric, string, Boolean) of the same type, true is returned if the value is the same, and false is returned if the value is different.

1 === 0x1; // true

The above code compares the decimal 1 with the hexadecimal 1, because the type and value are the same, it returns true.

It should be noted that NaN is not equal to any value (including itself). In addition, positive 0 is equal to negative 0.

(NaN ===
  NaN + // false
    0) ===
  -0; // true

(3) Composite type value

When comparing data of two composite types (objects, arrays, functions), it is not to compare whether their values ​​are equal, but to compare whether they point to the same address.

{} === {} // false
[] === [] // false
(function () {} === function () {}) // false

The above code compares two empty objects, two empty arrays, and two empty functions respectively, and the results are not equal. The reason is that for the values ​​of composite types, the strict equality operation compares whether they refer to the same memory address, and the values ​​of empty objects, empty arrays, and empty functions on both sides of the operator are stored in different memory addresses. The result is of course false.

If two variables refer to the same object, they are equal.

var v1 = {};
var v2 = v1;
v1 === v2; // true

Note that for the comparison of two objects, the strict equality operator compares the address, and the greater than or less than operator compares the value.

var obj1 = {};
var obj2 = {};

obj1 > obj2; // false
obj1 < obj2; // false
obj1 === obj2; // false

In the above three comparisons, the first two compare values, and the last one compares addresses, so all return false.

(4) undefined and null

undefined and null are strictly equal to themselves.

undefined === undefined; // true
null === null; // true

Since the default value of the variable after declaration is undefined, two variables that are only declared unassigned are equal.

var v1;
var v2;
v1 === v2; // true

Strictly inequality operator

The strict equality operator has a corresponding "strict inequality operator" (!==). Its algorithm is to find the result of the strict equality operator first, and then return the opposite value.

1 !== "1"; // true
// Equivalent to
!(1 === "1");

In the above code, the exclamation mark ! is to find the opposite value of the following expression.

Equality operator

When the equality operator is used to compare data of the same type, it is exactly the same as the strict equality operator.

1 == 1.0;
// Equivalent to
1 === 1.0;

When comparing different types of data, the equality operator will first convert the data, and then use the strict equality operator to compare. The following is divided into several situations to discuss the rules for comparing different types of values ​​with each other.

(1) Primitive type value

Values ​​of primitive types are converted to numeric values ​​and then compared.

1 == true; // true
// equivalent to 1 === Number(true)

0 == false; // true
// equivalent to 0 === Number(false)

2 == true; // false
// equivalent to 2 === Number(true)

2 == false; // false
// equivalent to 2 === Number(false)

"true" == true; // false
// equivalent to Number('true') === Number(true)
// equivalent to NaN === 1

"" == 0; // true
// equivalent to Number('') === 0
// equivalent to 0 === 0

"" == false; // true
// equivalent to Number('') === Number(false)
// equivalent to 0 === 0

"1" == true; // true
// equivalent to Number('1') === Number(true)
// equivalent to 1 === 1

"\n 123 \t" == 123; // true
// Because when the string is converted to a number, the leading and trailing spaces are omitted

The above code converts both string and Boolean values ​​into numeric values, and then compares them. For specific string and boolean type conversion rules, see the chapter "Data Type Conversion".

(2) Comparison of object and primitive type value

When an object (here, a generalized object, including arrays and functions) is compared with a value of a primitive type, the object is converted to a value of the primitive type and then compared.

Specifically, call the valueOf() method of the object first. If the value of the primitive type is obtained, compare with each other according to the rules of the previous section; if the obtained object is still an object, then call the toString() method to get String form, and then compare.

The following is an example of comparing an array with a primitive type value.

// Comparison of array and value
(((([1] == (1)[1]) == // Comparison of array and string // true
  "1"[(1, 2)]) == // true
  "1,2"[1]) == // Comparison of object and boolean // true
  true[2]) == // true
  true; // false

In the above example, the JavaScript engine will first call the valueOf() method of the array on the array [1]. Since the return is still an array, it will then call the toString() method of the array to get the string form. Then follow the rules in the previous section for comparison.

Here is a more direct example.

const obj = {
  valueOf: function () {
    console.log("Execute valueOf()");
    return obj;
  },
  toString: function () {
    console.log("Execute toString()");
    return "foo";
  },
};

obj == "foo";
// execute valueOf()
// Execute toString()
// true

In the above example, obj is an object with custom valueOf() and toString() methods. When this object is compared with the string 'foo', the valueOf() and toString() methods will be called in sequence, and finally 'foo' is returned, so the comparison result is true.

(3) undefined and null

undefined and null will return true only when compared with themselves or with each other; when compared with other types of values, the result is both false.

undefined == undefined; // true
null == null; // true
undefined == null; // true

false == null; // false
false == undefined; // false

0 == null; // false
0 == undefined; // false

(4) Disadvantages of the equality operator

The type conversion hidden by the equality operator can bring some counter-intuitive results.

0 == ""; // true
0 == "0"; // true

2 == true; // false
2 == false; // false

false == "false"; // false
false == "0"; // true

false == undefined; // false
false == null; // false
null == undefined; // true

"\t\r\n" == 0; // true

The above expressions are different from intuition and are prone to errors. Therefore, it is recommended not to use the equality operator (==), it is best to use only the strict equality operator (===).

Inequality operator

The equality operator has a corresponding "inequality operator" (!=). Its algorithm is to find the result of the equality operator first, and then return the opposite value.

1 != "1"; // false

// Equivalent to
!(1 == "1");