Can you explain why this line evaluates to true in JavaScript? console.log([] == ![]); // true An empty array…

Can you explain why this line evaluates to true in JavaScript? console.log([] == ![]); // true An empty array is equal to the negation of itself? It looks like a broken language feature, but the JavaScript engine follows strict internal conversion rules. Here is what happens under the hood during Implicit Type Coercion: 1. Strict Equality (===) vs Loose Equality (==) • Strict (===): Compares Type + Value. If types differ, it returns false immediately. No conversions occur. • Loose (==): Compares Value only. If types differ, the engine forces "Implicit Type Coercion" to convert both sides into a common type before comparing. 2. Decoding the Anatomy of [] == ![] Step 1: Operator Precedence The Logical NOT (!) operator executes first. In JavaScript, an array is an object, and all objects are truthy. Negating a truthy value turns it into boolean false: ![] ➔ false Now the check becomes: [] == false Step 2: The Boolean Coercion Rule When comparing anything to a Boolean with ==, the engine converts the Boolean to a Number (false becomes 0): [] == 0 Step 3: The Object-to-Primitive Rule When comparing an Object/Array to a Number, the engine calls .toString() on the object: [].toString() produces "" (an empty string). Now the check becomes: "" == 0 Step 4: The String-to-Number Rule When comparing a String to a Number, the engine converts the String to a Number: Number("") evaluates to 0. Step 5: The Final Comparison 0 == 0 ➔ true! 3. The Special Case: null and undefined null == undefined evaluates to true, but: null == 0 evaluates to false. Why? The specification explicitly dictates that null and undefined loosely equal each other and nothing else. They do not coerce to numbers under ==. 4. The Production Standard: This is why modern teams and ESLint enforce the strict equality rule (eqeqeq). Loose equality (==) introduces silent conversions that hide runtime logic bugs. Always default to strict equality (=== and !==) to keep comparisons explicit and predictable. Did you know why [] == ![] returned true before seeing the step-by-step trace?

19
Loading comments