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!

Oldest comments (4)

Collapse
 
andreybarkov profile image
Andrey Barkov

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

Collapse
 
ronakjethwa profile image
Ronak Jethwa • Edited

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
Collapse
 
ronakjethwa profile image
Ronak Jethwa • Edited

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

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));