Types & Coercioncritical

Type Coercion

JavaScript automatically converts values between types in certain contexts. String + Number uses string concatenation; comparison operators trigger numeric conversion. This is called implicit type coercion.

Memory anchor

Type coercion is JS playing telephone — you whisper 'five' and by the time it reaches the other end, it has become the number 5, the string '5', or boolean true. The + operator is the worst gossip: sees a string and turns everything into a string.

Expected depth

The + operator is overloaded: if either operand is a string, it concatenates. All other arithmetic operators (-,*,/) coerce to numbers. Abstract Equality (==) uses the Abstract Equality Comparison algorithm which coerces types. Key rules: null == undefined is true; null == 0 is false; false == 0 is true; '' == 0 is true; '' == false is true. Boolean conversion: 0, '', null, undefined, NaN, false are falsy; everything else (including [], {}, '0') is truthy.

Deep — senior internals

Type coercion routes through ToPrimitive(hint) → toString/valueOf. For + with an object, ToPrimitive is called with 'default' hint (which resolves to 'number' for most objects, but 'string' for Date). The algorithm first tries valueOf() then toString() for number hint, or toString() first for string hint. You can override this by defining [Symbol.toPrimitive](hint) on an object. This is why [] + [] is '', [] + {} is '[object Object]', and {} + [] is either 0 or '[object Object]' depending on whether {} is parsed as a block or object literal.

🎤Interview-ready answer

JavaScript coercion follows ToPrimitive rules: the + operator concatenates if either operand is a string, all other arithmetic coerces to number. Abstract equality (==) coerces per the spec's Abstract Equality Comparison — use === in production to avoid surprises. The most important coercion rules: falsy values are 0, '', null, undefined, NaN, false; [] and {} are truthy despite being 'empty'.

Common trap

[] == false is true but Boolean([]) is true — these are not contradictory but deeply confusing. == triggers ToNumber coercion on [] (gives 0) then compares 0 == 0. Boolean() applies ToBoolean rules where all objects are truthy. This is why if([]) runs the branch, but [] == false is true.