Equality operators in JavaScript

JavaScript

Equality operators in JavaScript

Comparing data in JavaScript

In JavaScript there are two commonly used value-comparison operators. They are the Strict Equality Comparison (===) operator and Abstract Equality Comparison (==). The result of these comparisons is always a boolean value of true or false. The Strict Equality Operator behaves identically to the Abstract Equality operator except no type conversion is done, and the types must be the same to be considered equal.

JavaScript uses Type Conversion to coerce any value to a Boolean in contexts that require it, such as conditionals and loops. The falsey values in JavaScript are false, null, undefined, NaN, 0 and ''. All other other values will coerce to truthy.

Boolean(false); //false
Boolean(null); //false
Boolean(undefined); // false
Boolean(NaN); //false
Boolean(0); //false
Boolean (''); //false
// Other values
Boolean({}); //true
Boolean(' '); //true
Boolean(1); //true

An important caveat is the JavaScript Object. As you see in the example above an object will converse to true no matter value it holds. Using the new keyword in JavaScript results in an Object being assigned to the variable - which means it will coerce to true no matter its content.

Boolean( new Boolean(false) ); //true -> coercing an Object
Boolean( Boolean(false) ); //false

Strict Equality Comparison

With Strict Equality Comparison the two values are directly compared. If the values have different types, the values are considered unequal and false is returned. If they are of the same type an intuitive equality test is applied: object identifiers must reference the same object, strings must contain identical character sets, other primitives must share the same value. A special case to this rule is the NaN primitive type that is not equal itself. Here are some examples:

const arrayOne = [1, 2, 3];
const arrayTwo = arrayOne;
const arrayThree = [...arrayOne];
const arrayFour = [1, 2, 3];

arrayOne === arrayTwo; //true, they point to the same Object
arrayOne === arrayThree; //false, although it is a copy they point to different arrays
arrayOne === arrayFour; //false

const stringZero = '0';
const helloWorld = "hello world";
const badMaths = 12 / 'hello'; //variable will be NaN

stringZero === '0'; //true
stringZero == 0; //false - they are different data types
helloWorld === "hello world"; //true
helloWorld === "Hello world"; // false - capitilisation of 'H' means they are not equal
badMaths === badMaths; //false
undefined === null; //false
null === null; //true
undefined === undefined; //true
NaN === NaN; //false

Abstract Equality Comparison

Abstract Equality Comparison (==) compares two values for equality converting both values to a common type if required. After conversions (one or both sides may undergo conversions), the final equality comparison is performed exactly as (===) performs it.

When comparing a Boolean to a non-Boolean, the Boolean is always converted to number. This means that true converts to 1 and false converts to 0.

When comparing a non-number to a number, the non-number will be converted to a number. So when comparing a non-number that cannot be converted to a number (e.g. "hello") the non-number will be converted to NaN which will always result in false

When comparing an object to an object, the comparison only returns true if both objects are referencing the same Object within memory. So new String("hello") == new String("hello") is false.

When comparing non-objects to objects, the objects are converted to primitives. This means that the toString and valueOf methods of the object are called. If they return a primitive (non-object), that return value is used, undefined and null are always considered equal to themselves and each other. Anything else compared to undefined or null will eventually evaluate to false. In most cases, comparison to undefined or null entails no conversion and immediately returns false.

[1, 2, 3] == [1, 2, 3]; //false Object to Object comparison require no type conversion and follows Strict Equality Comparison rules
[1,2,3]; == '1,2,3' //true Object is converted to a string and then compared
[0] == false; // true Boolean is converted to a number and compared
0 == false; // true
[0] == false; //true
[0] == false; //true

Summary

Knowing the way in which JavaScript converts types in Abstract Type Conversion can be valuable in some cases when writing clean JavaScript code. One example would be testing if an argument has been passed to a function:

function something(arg) {
  if (arg === undefined || arg === null) {}
}

//being the exact equivalent of:

function something(arg) {
  if (arg == null) {}
}

As for which comparison operator to use, Mozilla Developer Network states:

Strict equality is almost always the correct comparison operation to use.

However, knowing how abstract equality works can be useful in certain instances, and knowing this part of the specification can help us write cleaner code in the future. If you have further information to add, contact me via Twitter @rhysonrails or click the email link below to send me an email.