Why JavaScript Has Weird Type Coercion
JavaScript's notorious type-coercion behavior, where 1 == "1" is true, "5" + 3 yields "53", and [] == ![] is also true, is a historical artifact of the language's 10-day origin at Netscape in May 1995. Marketing pressure to resemble Java, a forgiving design aimed at beginner web authors, and a strict no-break-the-web compatibility doctrine froze the rules into the standard.
JavaScript was prototyped in roughly ten days in May 1995 by Brendan Eich at Netscape, who had been hired to embed a Scheme-like scripting language in the Netscape Navigator browser. By the time he arrived, the company had signed a marketing alliance with Sun Microsystems and management decided the new language had to "look like Java" so it could be sold as Java's little sibling for casual page authors. The result was a hybrid: C-style syntax from Java wrapped around first-class functions and prototype-based objects borrowed from Scheme and Self. The first shipping name was Mocha, then LiveScript, then JavaScript in December 1995, chosen for co-branding rather than technical kinship. Because the intended audience was beginning HTML authors pasting snippets into web pages, the language was designed to almost never throw at runtime. Missing properties returned undefined, arithmetic on incompatible values produced NaN rather than errors, and the double-equals operator silently converted operands to a common type. The Abstract Equality Comparison algorithm coerces strings to numbers, booleans to numbers, and objects to primitives before comparing, which is why 1 == "1" is true and [] == ![] is also true (both sides reduce to 0 via the empty-string and number conversion paths). The plus operator is overloaded: "5" + 3 concatenates because either string operand wins, while "5" - 3 subtracts to 2 because minus only means number. These behaviors were convenient for form-validation scripts in 1995 but produced the famously surprising outputs that Gary Bernhardt compiled into the 2012 lightning talk "Wat," including Array(16).join('wat' - 1) yielding a string of NaNs. When the language was standardized as ECMAScript by Ecma International (Edition 1 in 1997, Edition 3 in 1999), the committee that became TC39 adopted a firm backward-compatibility rule: changing existing operator behavior would break millions of live web pages whose authors could not be contacted. Instead of fixing ==, ECMAScript 3 added Strict Equality (JavaScript) (===) as an opt-in workaround that compares without coercion. The original coercion table is therefore still law, preserved as what Allen Wirfs-Brock and Eich call the "don't break the web" constraint in their 2020 HOPL paper "JavaScript: The First 20 Years." Modern style guides and linters route around the rules by mandating ===, but the rules themselves cannot be removed without invalidating three decades of deployed code.