As it turns out, there is a straightforward way to decide which one to use. And the same logic works for inequality comparison operators !== and != as well.
Compare equal and of same type with ===
The triple equals operator (===) returns true if both operands are of the same type and contain the same value. If comparing different types for equality, the result is false.
This definition of equality is enough for most use cases. When comparing the string "0" and the number 0 the result is false as expected.
Complex type conversions take place with ==
The double equals operator (==) tries to perform type conversion if the types differ and then compare for equality. If the types differ, either or both operands are first converted to a common type. The conversion rules are complex and depend on the argument types. For a full comparison table, see for example MDN or the ECMAScript specification.
For example, when comparing the string "0" and the number 0, the first argument is first converted to a number.
While the string and number comparison is understandable, the complex rules for other types lead to illogical results. For example, see the comparisons between null, undefined and false:
Now you know - only use ===
Use the triple equals (===) equality comparison operator. When trying to compare different types with triple equals, the result is always false. You will get the results you expect that are not subject to hard to memorize conversion rules. Comparing apples to oranges is false as expected.
Note that these comparison operators are for comparing primitive types. For comparing deep equality of objects or arrays a different approach is needed that compares the operands structurally.
Semantic Versioning Cheatsheet
Learn the difference between caret (^) and tilde (~) in package.json.