skip to content

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 pageshow

explore

questions

61 · 4 sections

In 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?

level: juniorimportance: must knowfreq 82%
basics
~20 s

typeof 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.

open as a page

Name the seven primitive types in JavaScript and explain what makes a value a primitive rather than an object.

level: juniorimportance: must knowfreq 80%
basics
~10 s

JavaScript 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.

open as a page

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?

level: middleimportance: must knowfreq 58%
basics
~20 s

Each 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.

open as a page

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?

level: middleimportance: must knowfreq 78%
basics
~20 s

Assignment 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.

open as a page

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?

level: middleimportance: must knowfreq 70%
basics
~20 s

undefined 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.

open as a page

In JavaScript, what does the == (loose equality) operator do that === does not, and what do '5' == 5 and '5' === 5 each evaluate to?

level: juniorimportance: must knowfreq 86%
basics
~20 s

The == 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.

open as a page

In JavaScript, what does the strict equality operator === compare, and how does it behave when its two operands have different types?

level: juniorimportance: must knowfreq 88%
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.

open as a page

In JavaScript, why does '5' + 3 give '53' while '5' - 3 gives 2? Explain what the + operator does with mixed operand types.

level: juniorimportance: must knowfreq 70%
basics
~20 s

Binary + 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.

open as a page

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?

level: juniorimportance: must knowfreq 85%
basics
~20 s

JavaScript 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.

open as a page

In JavaScript, the expression '0' == false evaluates to true. Walk through the loose-equality conversion steps that produce that result.

level: middleimportance: must knowfreq 58%
basics
~20 s

A 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.

open as a page

In JavaScript, why does `0.1 + 0.2 === 0.3` evaluate to false, and what does `0.1 + 0.2` actually produce?

level: juniorimportance: must knowfreq 88%
basics
~10 s

JavaScript 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.

open as a page

In JavaScript, why does NaN === NaN evaluate to false, and how do you reliably test whether a value is NaN?

level: juniorimportance: must knowfreq 72%
basics
~10 s

NaN 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.

open as a page

How should you compare two computed JavaScript numbers for approximate equality, and what does `Number.EPSILON` actually represent?

level: middleimportance: must knowfreq 58%
basics
~20 s

Number.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.

open as a page

In JavaScript, why does the expression 9007199254740993 === 9007199254740992 evaluate to true, and what does Number.MAX_SAFE_INTEGER have to do with it?

level: middleimportance: must knowfreq 65%
basics
~20 s

A 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.

open as a page

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?

level: middleimportance: must knowfreq 58%
basics
~10 s

The 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.

open as a page

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?

level: juniorimportance: must knowfreq 65%
basics
~20 s

JavaScript 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.

open as a page

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?

level: juniorimportance: must knowfreq 58%
basics
~20 s

A 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.

open as a page

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?

level: juniorimportance: must knowfreq 80%
basics
~20 s

A 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.

open as a page

Why does `'🙂'.length` evaluate to 2 in JavaScript, and how do you count what a user would call one character?

level: middleimportance: must knowfreq 58%
basics
~20 s

JavaScript'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.

open as a page

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?

level: middleimportance: must knowfreq 52%
basics
~20 s

The 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.

open as a page