Silvia Pan Logo
August 22, 2019

Equality Comparison of JavaScript Data Types

JavaScript data types

Data types specify what kind of value a variable can have. According to the latest ECMAScript Standard, JavaScript contains eight data types.

They are separated into two categories: primitive and complex.

Primitive data types

  • String - characters inside quotations
  • Number - integers and floats
  • BigInt - integer larger than 253 (largest value for a Number type)
  • Boolean - true or false
  • Null - non-existing value
  • Undefined - declared variable but unassigned value
  • Symbols - unique identifiers of objects

Complex data type

Everything else that’s not a primitive data type belongs to a category called Objects.

  • Objects - collection of different types of data

Objects (data type) include everything from functions to arrays.

We will focus on objects and arrays.

// object
const book = {
  id: 1,
  title: 'Red Dragon',
  genre: 'Fiction',
};

// array
const library = [
  {
    id: 1,
    title: 'Red Dragon',
    genre: 'Fiction',
  },
  {
    id: 2,
    title: 'It',
    genre: 'Horror',
  },
];

Equality comparison

When comparing values, a loose equality comparison (==) or strict equality comparison (===) can be used.

Loose equality comparison

If two values are of different data types, they are converted to be the same data type first. After conversion, their values are then compared for equality.

// all comparisons are true

/* no conversion
1 is equal to 1
*/
1 == 1;

/*
1 is converted to '1'
'1' is equal to '1'
*/
1 == '1';

/*
1 is converted into true
true is equal to true
*/
1 == true;

Strict equality comparison

Unlike loose equality comparison, no conversion happens before the values are compared for equality. Therefore, when using === data type and values must be equal for it to return true.

1 === 1; // true

/* 
false - data type differs 
(number vs. string)
*/
1 === '1';

/* 
false - data type differs
(number vs. boolean)
*/
1 === true;

Since both == and === are equality comparisons, which one is preferred?

Stick with === because no assumptions are being made about conversions.

As you can see, loose equality (==) conversions can get quite funky.

Compare primitive data types

We’ve seen a few examples above of comparing primitive types. If the values are equal, comparison returns true. You can also declare variables and compare them.

'red' === 'red'; // true

const color1 = 'red';
const color2 = 'blue';

color1 === 'red'; // true
color1 === color2; // false

When comparing strings, keep in mind that it is case-sensitive.

Each character in the string is compared. Therefore, the strings red and Red are not equal.

Compare objects and arrays

Comparing objects and arrays is different from comparing primitive types, such as numbers and strings.

Let’s take a look at the example below.

const color1 = 'red';
const color2 = 'red';
color1 === color2; // true

const colors1 = ['red'];
const colors2 = ['red'];
colors1 === colors2; // false

Why is the first equality comparison true, but the second one false?

Comparison for the primitive data types compares values, whereas non-primitive types (e.g. objects and arrays) compare their references.

Object references

References refer to the location of where the data is stored in the computer’s memory. The arrays colors1 and colors2 occupy two different spaces in memory.

For simplicity’s sake, let’s visualize the computer’s memory as a grid of 5 squares.

1 2 3 4 5

Let’s say at square 1 is the start of colors1 array and at the square 3 is the start of colors2 array. The location 1 and 3 are the arrays’ references.

When comparing arrays, their references are being compared — not the value found at the references.

Therefore, rather than comparing the contents within the array, you’re comparing if 1 is equal to 3. Since 1 doesn’t equal 3, the equality comparison returns false.

Even if you do just [‘red’] === [‘red’], the result is still false because each array occupies a different space in memory.

It helps to think of objects and arrays as houses. They contain a collection of different items, i.e. data, inside.

Even if the two houses are identical on the inside, if one’s address is 123 Maple St. and another is 456 Oak St. they’re still two different houses.

How to actually compare objects and arrays

Two rules for comparing objects and arrays

  1. They must be the same size (or length)
  2. All the values inside must be equal

Array

const arr1 = [1, 2, 3, 'abc'];
const arr2 = [1, 2, 3, 'abc'];

arr1 === arr2; // false

function checkArrayEquality(arr1, arr2) {
  // first check if the arrays are the same size
  if (arr1.length !== arr2.length) {
    return false; // equal arrays must be the same size
  }

  // loop through each element to check if they're equal
  for (let i = 0; i < arr1.length; i++) {
    if (arr1[i] !== arr2[i]) {
      return false; // each element must be equal
    }
  }
  return true; // after passing all checks the arrays should be equal
}

checkArrayEquality(arr1, arr2); // true

You might have noticed this function doesn’t work if the arrays are sorted differently.

If I do checkArrayEquality([1,2,3], [3,2,1]) it returns false even though I expect it to be true.

In order for this function to work, the arrays must also be sorted. We can add in arr1.sort() and arr2.sort() right before the loop to sort the arrays first.

Hurray the function works now! …Except you now need to compare nested arrays.

Would this function still work?

const arr1 = [1, 2, [3, 4]];
const arr2 = [1, 2, [3, 4]];

checkEqualityArray(arr1, arr2); // false

The function returns false. The problems occurs when looping through and comparing each element.

1 === 1; // true
2 === 2; // true
[3, 4] === [3, 4]; // false

When the loop reaches the two arrays, we’re checking if they’re equal to each other. Since the two arrays’ references aren’t the same, [3, 4] === [3, 4] will return false. The function then stops running.

While it’s possible to write your own function to compare deeply nested objects and arrays, I’d recommend using a library, such as lodash, to compare them. There’s no need to reinvent the wheel, especially when there’s a well-documented and -supported library.

Lodash is a popular library that has an _.isEqual function to compare objects and arrays. Learn more about Lodash’s isEqual function

Comparing all data types

When comparing any values, first determine if they’re primitive data types or not.

Non-primitive data types, i.e. objects, cannot be compared using equality operator because it compares their references (location in memory). If the objects or arrays are flat and not nested, feel free to write your own helper function to check for equality.

However, if they’re nested, it’ll be easier to use a library. The library will handle checking that every value within the object is equal.

Every other type besides objects can be compared simply with == or ===.

© 2023 Silvia Pan