JavaScript

JavaScript: Loose Equals and Strict Equals

Is implicit coercion evil and harmful? In certain cases, yes! In a broad sense, not really.


Loose equals refers to the “==” (double equal sign) operator, while Strict equals indicates the “===” (triple equal sign) operator. Usually both these operators are utilized in the comparison of two values and check for “equality”. However, the “loose” and the “strict” equals have a significant difference in their behaviors, especially in the way they conclude “equality”.

A common misconception about the two operators turns out to be: “double equal sign checks the values for equality while triple equal sign checks both values and their types for equality”. Although it sounds and seems quite reasonable and distinct, it is fundamentally incorrect. There are multiple popular JavaScript books as well as blogs that have indicated exactly this distinction, but unfortunately they’re all wrong.

The more appropriate definition would be: “double equal sign allows coercion in the equality comparison while the triple equal sign operation avoids coercion.”

Performance Comparisons of the Two Equalities

Let’s take a moment and consider the two definitions, first the incorrect one and then the more appropriate one.

Observe that in the first explanation, it simply indicates that the operator “===” is working more than the operator “==”. This seems obvious since it involves checking the type. But consider the second explanation where “==” is getting more work done, as it follows through the steps of coercion in case of different types.

Beware of this trap! Many people think that this has a link with performance since “==” works relatively slower. Although it is quantitatively valid that the coercion process takes a considerable amount of processing time, however the additional time is in microseconds.

Alternatively, while considering the comparison of two different values of the same type, the “==” operator and the “===” operators both use the same algorithm. Therefore they should be doing the same amount of work, even if we include the minute differences in their corresponding engineer implementation.

Now in case we’re comparing two distinct values, performance is not necessarily the major point of concern. Instead we should rather revisit the requirement of having the coercion process or not. If we truly want to have coercion, we opt for the “==” for the loose equality, otherwise we go for the “===” strict operator.

Note: Here, the major implication is that both the operators (“==” and “===”) check for the type of their operands. The difference lies in the manner in which they respond in case of a mismatch in the types.

Abstract Equality

The behavior of the “==” operator is defined as “The Abstract Equality Comparison Algorithm” under section 11.9.3 of ES5 specification. This section indicates how the coercion process (if required) should take place for each possible type of combination through a comprehensive yet simplified algorithm.

In other words, the first clause under this section (i.e. 11.9.3.1) mentions that in cases where the two values being compared falls within the same type, they are expected to be compared, simply and naturally, through identity. That means, consider “123” which is only equal to “123” just as how “qwerty” should only be equal to “qwerty”.

The final segment of the clause 11.9.3.1 is dedicated to the comparison of the “==” loose equality with objects (including functions and arrays). Here, two such values can only be considered equal if and only if they refer to the exact same value. Thus, no coercion is observed here.

The remaining part of the algorithm under 11.9.3 section mentions that when using the “==” loose equality operator while comparing two values of different types, there may arise the need to implicitly coerce either one or both values. This occurs to ensure that the two values eventually turn out to be of the same type, which can hence be directly used to compare for equality through simple value identity.

Note: The “!=” loose not-equality operator is also defined exactly as we would expect. It is simply the complete “==” operation comparison performed, after which the result is negated. Similarly the “!==” is used as the strict not-equality operator.

Safe Use of the Implicit Coercion

Let’s set up one simple ground rule: Always go through the program and reason about the values which might show up on either side of the “==” comparison. In order to avoid pertaining to comparisons, you may follow the the below norms:

  • In cases where either side of the comparison can have a true or false value, always avoid using the “==” operator.
  • In cases where either side of the comparison can have [], “” (empty string), or 0 values, again avoid the usage of “==” operator.

In the above cases, it’s way better to utilize the “===” operator in place of the “==” operator so as to avoid coercion. If these two rules are kept in hand, a lot of troubles related to coercion procedure could be easily dodged. In these cases, being more clear-cut and wordy will help avoid a lot of trouble.

So now, the more apt form of question regarding the comparison of the “==” and “===” operators would be: Should a coercion be allowed for comparison?

There exist multiple situations where coercion can be handy, enabling us to frame some comparative logics in a much brief manner (such as undefined or null, for example). On the contrary, there are comparatively fewer cases where implicit coercion can be quite harmful. In such cases, however, it’s strongly recommended to use the “===” operator as a precaution.

Now the question: Is implicit coercion evil and harmful? In certain cases, yes! In a broad sense, not really.

Conclusion

It’s important to be a responsible and mature developer. Learning and gaining the experience of the power to use coercion (both explicit and implicit) seamlessly and effectively, as well as transferring the knowledge to others, is the key here.