Types and Coercion
JavaScript has no static types at runtime, so every value carries its own type and the engine converts between them implicitly. Interviewers probe this constantly because coercion is where the language's most famous surprises live — and because reasoning about it separates people who memorized rules from people who understand the conversion algorithms.
part ofJavaScriptoverview, primer and where to startread it →on this pageshowhide
explore
- Primitives and Objects13 questions
- The Seven Primitive Types5 questions
- Wrapper Objects and Autoboxing4 questions
- Runtime Type Detection4 questions
- Equality and Conversion18 questions
- Loose Equality and the == Algorithm5 questions
- ToPrimitive, valueOf, and toString5 questions
- Truthy, Falsy, and ToBoolean4 questions
- Numbers and Numeric Types15 questions
- IEEE-754 Floats and Precision5 questions
- NaN, Infinity, and Negative Zero5 questions
- Safe Integers and BigInt5 questions
- Strings and Symbols15 questions
- Template Literals and Tagged Templates5 questions
- String Immutability and UTF-165 questions
- Symbols and Well-Known Symbols5 questions
questions
61 · 4 sectionsIn JavaScript, what does the typeof operator return for null, for an array, for a function or class, and for a variable that was never declared?
basics
~20 stypeof null returns "object" — a historic bug kept for compatibility. Arrays return "object" too, so typeof cannot spot them. Functions and classes return "function". typeof on a never-declared name safely returns "undefined" instead of throwing.
Name the seven primitive types in JavaScript and explain what makes a value a primitive rather than an object.
basics
~10 sJavaScript has seven primitives: string, number, boolean, null, undefined, symbol and bigint. Everything else is an object. Primitives are immutable, hold no properties of their own, and are copied and compared by their value.
An array built inside an iframe is handed to the parent page, where value instanceof Array evaluates to false even though the value genuinely is an array. Why does instanceof fail here, and what check works instead?
basics
~20 sEach iframe is a separate realm with its own Array constructor and Array.prototype, so a foreign array's prototype chain never reaches the parent's Array.prototype and instanceof is false. Array.isArray reads the internal array brand and works across realms.
In JavaScript, how does assigning a primitive to another variable differ from assigning an object, and what does that mean for a value you pass into a function?
basics
~20 sAssignment always copies a value. For a primitive that value is the data itself, so the two variables are independent. For an object the value is a reference, so both names point at one object and a mutation through either is visible through both.
In JavaScript, what is the difference between null and undefined, and why does a default parameter value apply when an argument is undefined but not when it is null?
basics
~20 sundefined is the absence the language itself produces: unassigned variables, missing arguments, missing properties, functions with no return. null is an absence a programmer assigns deliberately. Default parameter values fire only for undefined, never for null.
In JavaScript, what does the == (loose equality) operator do that === does not, and what do '5' == 5 and '5' === 5 each evaluate to?
basics
~20 sThe == operator converts operands to a common type before comparing; === requires matching types and never converts. So '5' == 5 is true, because the string is converted to the number 5, while '5' === 5 is false.
In JavaScript, what does the strict equality operator === compare, and how does it behave when its two operands have different types?
basics
~20 s=== returns true only when both operands have the same type and the same value. Different types are never converted, so the result is immediately false. Objects and arrays compare by reference, not by contents.
In JavaScript, why does '5' + 3 give '53' while '5' - 3 gives 2? Explain what the + operator does with mixed operand types.
basics
~20 sBinary + is the only arithmetic operator that is also string concatenation: after converting both operands to primitives, if either one is a string it concatenates, otherwise it adds numerically. Every other arithmetic operator converts to number unconditionally, so '5' - 3 is 2.
In JavaScript, which values are falsy — that is, which convert to false when used as an `if` condition — and which commonly-assumed-falsy values are actually truthy?
basics
~20 sJavaScript has a fixed falsy list: false, 0, -0, 0n, the empty string, null, undefined, and NaN. Every other value is truthy — including '0', 'false', the empty array, the empty object, and every function.
In JavaScript, the expression '0' == false evaluates to true. Walk through the loose-equality conversion steps that produce that result.
basics
~20 sA boolean operand is converted to a number first, so false becomes 0 and the comparison becomes '0' == 0. The string is then converted with ToNumber to 0, so 0 == 0 is true. Booleans are never compared as booleans.
In JavaScript, why does `0.1 + 0.2 === 0.3` evaluate to false, and what does `0.1 + 0.2` actually produce?
basics
~10 sJavaScript numbers are IEEE-754 binary doubles, and 0.1, 0.2 and 0.3 cannot be written exactly in binary. The stored approximations add up to 0.30000000000000004, a different double from 0.3, so === is false.
In JavaScript, why does NaN === NaN evaluate to false, and how do you reliably test whether a value is NaN?
basics
~10 sNaN is the only JavaScript value not equal to itself: IEEE-754 makes every comparison involving NaN false, so === and indexOf never find it. Test with Number.isNaN(x), which checks the value without converting it.
How should you compare two computed JavaScript numbers for approximate equality, and what does `Number.EPSILON` actually represent?
basics
~20 sNumber.EPSILON is the gap between 1 and the next representable double, about 2.22e-16 — a relative spacing near 1, not a universal error bound. Compare with a tolerance scaled to the operands' magnitude, not a fixed epsilon.
In JavaScript, why does the expression 9007199254740993 === 9007199254740992 evaluate to true, and what does Number.MAX_SAFE_INTEGER have to do with it?
basics
~20 sA JavaScript number carries 53 bits of significand, so integers above 2^53 can no longer all be represented; the literal 9007199254740993 rounds to 9007199254740992 at parse time. Number.MAX_SAFE_INTEGER, 2^53 - 1, marks the last integer whose successor is still distinct.
How do JavaScript's global isNaN() and isFinite() differ from Number.isNaN() and Number.isFinite(), and which would you use to validate a numeric field?
basics
~10 sThe global isNaN and isFinite convert their argument to a number first, so isNaN("") is false and isFinite("100") is true. The ES2015 Number.isNaN and Number.isFinite never convert: any non-number returns false.
In JavaScript, what happens when you assign to a character position of a string, as in `let s = 'hello'; s[0] = 'H';`, and what does that tell you about how string methods behave?
basics
~20 sJavaScript strings are immutable, so the assignment silently does nothing in sloppy mode and throws a TypeError in strict mode; s stays "hello". Every string method, such as toUpperCase or trim, returns a brand-new string instead of editing the original.
In JavaScript, what is a Symbol, and what does using a symbol as an object property key give you that a string key does not?
basics
~20 sA Symbol is a primitive whose every value is unique: Symbol('id') never equals another Symbol('id'). Used as a property key, it cannot collide with any string key or with symbols created by other code, even when the descriptions match.
In JavaScript, what is a template literal (a string written in backticks), and how does it differ from building the same string with the + operator?
basics
~20 sA template literal is a backtick-delimited string that embeds any expression with ${...} and keeps newlines exactly as typed. Interpolated values are converted to strings automatically, so it produces what + would for most inputs, with far less quote juggling.
Why does `'🙂'.length` evaluate to 2 in JavaScript, and how do you count what a user would call one character?
basics
~20 sJavaScript's .length counts UTF-16 code units, not characters. The 🙂 emoji sits above the Basic Multilingual Plane, so it is stored as a two-unit surrogate pair. Iterating the string, for example with [...str], walks whole code points and yields 1.
When you call a JavaScript tagged template such as tag`a${x}b`, what arguments does the tag function actually receive, and what is the relationship between them?
basics
~20 sThe tag function receives the static text chunks as its first argument — an array with a raw property holding the unescaped text — followed by one argument per interpolated value. The chunks array always has exactly one more element than the number of values.