DEV Community

loading...
Cover image for Never again, be stumped by JS Abstract Equality 🤔

Never again, be stumped by JS Abstract Equality 🤔

sagarrth profile image Sagar Routh ・2 min read

JavaScript has Strict Equality a.k.a === comparison and Abstract Equality a.k.a == comparison. It is the latter's lack of understanding which might cause bugs.



Rules

rule

These are the rules which come into effect while resolving the abstract equality -

  1. If x=null and y=undefined, return true;
  2. If x=undefined and y=null, return true;
  3. If Type(x) is same as Type(y) then perform strict equality comparison.
  4. If Type(x)=Number and Type(y)=String, return result of x==ToNumber(y)
  5. If Type(x)=String and Type(y)=Number, return result of ToNumber(x)==y
  6. If Type(x)=Boolean, return result of ToNumber(x)==y
  7. If Type(y)=Boolean, return result of x==ToNumber(y)
  8. If Type(x) is either String, Number or Symbol & Type(y) is Object, then return result of x==ToPrimitive(y)
  9. If Type(y) is either String, Number or Symbol & Type(x) is Object, then return result of ToPrimitive(x)==y
Type, ToNumber, ToBoolean are all abstract operations, they are implemented by the JS engine

ToPrimitive, ValueOf, ToString

8th and 9th cases are quite interesting. It involves the conversion of a non-primitive value to a primitive one.

According to the spec, the ToPrimitive method accepts two arguments - Input and optional PreferredType hint (it could be either string, number or default).

An object utilizes the following two methods for conversion if the ToPrimitive is not available for the object -

  1. valueOf - takes precedence in case of number hint i.e during numerical comparisons, followed by a call to toString, if the former does not yield a primitive value

  2. toString - takes precedence in case of string hint, followed by a call to valueOf, if the former does not yield a primitive value

For the default hint case, it's considered as number unless the object is of Date type.

Enough talking, let's see code in action for the above statements


Implementing ToPrimitive

Symbol.toPrimitive is the way to implement an object's toPrimitive operation. If this method does not return a primitive, then an error is thrown. The snippet below shows how one could implement any custom logic for object coercion.


Reference:

That's all people!

thankyou

Discussion (0)

pic
Editor guide