DEV Community

Ronak Jethwa
Ronak Jethwa

Posted on

JavaScript Equality Checks

Some Fun Equality Checks In JavaScript

There are mainly 3 ways to check the value equality in JavaScript. You already know two of them. There is a fun third one, Object.is().

- Strict Equality: a === b (triple equals).
- Loose Equality: a == b (double equals).
- Same Value Equality: Object.is(a, b).
Enter fullscreen mode Exit fullscreen mode
// Zero, look closely!
-0 == 0; // true
-0 === 0; // true
Object.is(-0,0); // false
Enter fullscreen mode Exit fullscreen mode
// One, an obvious one!
-1 == 1; //false
-1 === 1; // false
Object.is(-1,1); // false
Enter fullscreen mode Exit fullscreen mode
// NaN, look closely again!
NaN == NaN; // false
NaN === NaN; // false
Object.is(NaN,NaN); // true
Object.is(NaN, 0/0); // true
Enter fullscreen mode Exit fullscreen mode
// String, one more obvious one!
'foo' == 'foo'; // true
'foo' === 'foo'; // true
Object.is('foo', 'foo'); // true
Enter fullscreen mode Exit fullscreen mode
// Array
[] == []; // false
[] === []; // false 
Object.is([], []); // false
Enter fullscreen mode Exit fullscreen mode
// Objects
var foo = { a: 1 };
var bar = { a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // false

// One more, for better clarity
let banana = {};
let cherry = banana;
let chocolate = cherry;
cherry = {};

Object.is(banana, cherry); // false
Object.is(cherry, chocolate); // false
Object.is(chocolate, banana); // true
Enter fullscreen mode Exit fullscreen mode
// Null
null == null; // true
null === null; // true
Object.is(null, null); // true
Enter fullscreen mode Exit fullscreen mode

Quick Recap

This tells us Object.is() is way more superior check than === in JavaScript. It handles two special cases where === fails horribly.

// Special Cases
-0 === 0; // true
Object.is(0, -0); // false

NaN === NaN; // false
Object.is(NaN, NaN); // true
Enter fullscreen mode Exit fullscreen mode

Additional: Implementation of === Function strictEquals

function strictEquals(a,b){
  // handle special cases, else return the right value!
  if (Object.is(a,NaN) || Object.is(b,NaN)) return false;
  if (Object.is(a,-0) && Object.is(b,0)) return true;
  if (Object.is(a,0) && Object.is(b,-0)) return true;
  return Object.is(a, b);
}
Enter fullscreen mode Exit fullscreen mode

Ciao!

Discussion (4)

Collapse
ronakjethwa profile image
Ronak Jethwa Author • Edited on

Fun Fact: with nested objects, the nested object property is copied by reference as a property to the new Object.

let user = {
  name: "John",
  sizes: {
    height: 182,
    width: 50
  }
};

let clone = Object.assign({}, user);

console.log(Object.is(user,clone)); //false
console.log(Object.is(user.sizes, clone.sizes)); //true

To avoid this, the easiest way in JavaScript to deep clone an object is

let clone2 = JSON.parse(JSON.stringify(user));
console.log(Object.is(user.sizes, clone2.sizes)); // false
Collapse
ronakjethwa profile image
Ronak Jethwa Author

DeepClone Utility Method

function deepClone(obj) {
    let cloneObj = {};
    for(let prop in obj) {
        if(typeof obj[prop] === 'object') {
            cloneObj[prop] = deepClone(obj[prop]);
        } else {
            cloneObj[prop] = obj[prop];
        }
    }
    return cloneObj;
}

let clone = deepClone(user);
console.log(Object.is(user.sizes,clone.sizes));
Collapse
andreybarkov profile image
Andrey Barkov

Can it be used to compare two different objects with same properties?

Collapse
ronakjethwa profile image
Ronak Jethwa Author • Edited on

Yes. Two different Objects with same properties are still two different objects with different memory references, so that would still return false with Object.is().

let user1 = {name: 'John', age:29};
let user2 = {name: 'John', age:29};
Object.is(user1,user2); // false

Although, this will be different.

let user1 = {name: 'John', age:29};
let user2 = user1
Object.is(user1,user2); // true