Javascript Interview Question: Implement abstract equality algorithm

Difference between == and ===, that you don’t know yet

Photo by Anna Shvets:

If we ask the difference between == and ===, the majority of people will say that == does loosely type checking whereas === does type + value checking.

Which is not the whole truth.

This is completely wrong.

== or Abstract equality also does the type checking in fact, type checking is the first thing that == does.

So what is the difference between == (Abstract Equality) and === (Strict Equality)?

Let’s find out together.

== (Abstract Equality) does 4 special things, if we are comparing two variables x and y.

1. Check the type of both variables.

if the type of x and type of y is the same, then do a strict equality check and return the result.

1 == 1;
Internally return 1 === 1

2. Check for null and undefined

If x is null and y is undefined, return true

If x us undefined and y is null, return true

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

3. ToPrimitive Conversion of non-primitives

if we compare non-primitives like Object and arrays, == (Abstract Equality) first convert them to their non-primitive equivalent by calling toString() method.

[] == ""; // [ ] will be converted into string
[].toString() == "";
"" == ""; // true

4. Convert to Number (== loves Number)

If x is of type Number, then convert y to Number by wrapping y in a Number function call, and then compare the result.

If y is of type Number, then convert x to Number by wrapping x in a Number function call, and then compare the result.

"1" == 1; // "1" will be converted into Number
Number("1") == 1
1 == 1 // true

So by seeing the above steps we can conclude that, == (Abstract Equality) does the type coercion while comparing variables, whereas ===(Strict Eqaulity) does not do any kind of type coercion.
And this is the real difference between == and ===.

Here is the rough Implementation of the Abstract Equality Algorithm:

function abstractEquality(value1, value2) {
// Step 1: If the types are the same, perform a regular equality check
if (typeof value1 === typeof value2) {
return value1 == value2;
}

// Step 2: If one of the values is null and the other is undefined, they are equal
if ((value1 === null && value2 === undefined) || (value1 === undefined && value2 === null)) {
return true;
}

// Step 3: If one of the values is a number and the other is a string, perform numeric string conversion
if ((typeof value1 === 'number' && typeof value2 !== 'object') ||
(typeof value1 !== 'object' && typeof value2 === 'number')) {
return Number(value1) == Number(value2);
}

// Step 4: If one of the values is an object, perform string conversion
if (isObject(value1) || isObject(value2)) {
return String(value1) == String(value2);
}

// Step 5: In all other cases, the values are not equal
return false;
}

// Helper function to check if a value is an object
function isObject(value) {
return typeof value === 'object' && value !== null;
}

I hope now you will be able to easily solve and reason about popular JS tricky questions like:

// 1
[] == false;

// 2
[1] == 1;

// 3
{} == "";

Here is the office spec link of Abstract Equality in case you want to dig deeper.
https://262.ecma-international.org/5.1/#sec-11.9.3

--

--