JavaScript Data Types

Understand how JavaScript classifies, stores, converts, compares, and evaluates values.

1. What is a Data Type?

A data type defines the kind of value a piece of data represents, how much memory it occupies, and what mathematical or logical operations can be performed on it.

JavaScript is dynamically typed (loosely typed). You do not declare variable types explicitly (like int or String in Java/C++). Instead, types are attached to the underlying value at runtime.

let value = 42;        // Currently holding a Number
value = "Hello";       // Now holding a String
value = true;          // Now holding a Boolean

๐Ÿ’ก Important Distinction: Variables vs Values

โ€ข Variables do not have fixed types; they are simply labeled containers that can point to different values over time.
โ€ข Values have concrete types (e.g. the literal 42 is always a Number; "Hello" is always a String).

2. The 7 Primitive Types

JavaScript has 7 primitive data types. Primitives hold raw values directly in Call Stack memory and are immutable.

๐Ÿงช Deep-Dive: 7 Primitive Types Explorer
Interactive Guide

Number

64-bit IEEE 754 Floating Point Format
typeof === "number"

Represents both integers and decimal numbers using 64-bit IEEE 754 format. Safely handles integers up to ยฑ(253 - 1). Includes special values: NaN, Infinity, and -Infinity.

Category Primitive Type
Memory Storage Call Stack (Fixed 8 Bytes)
Mutability Immutable
typeof Output "number"
Example Code & Usage
let age = 25;                       // Integer
let price = 99.99;                   // Decimal float
let safeMax = Number.MAX_SAFE_INTEGER; // 9007199254740991
let inf = 1 / 0;                     // Infinity
let notANum = 0 / 0;                 // NaN
๐Ÿ’ก Key Rule & Interview Tip: There is no separate int or float type in JavaScript. 42 and 42.0 are the exact same type in memory. Remember: typeof NaN === 'number', and NaN === NaN is false!

3. Primitive vs Reference Types (Memory Model)

How JavaScript values live and behave in memory is the single most tested concept in technical interviews:

01

Primitive Types (Stack Memory)

  • Stored directly in the fast Call Stack
  • Fixed memory size, immutable in place
  • Copied by value (copying creates an independent value)
Example (Copy by Value)
let x = 10;
let y = x; // independent copy
y = 20;

console.log(x); // 10 (untouched)
console.log(y); // 20
02

Reference Types (Heap Memory)

  • Objects, Arrays, Functions stored in the flexible Heap
  • Dynamic expandable memory size
  • Copied by reference (both point to the same memory address)
Example (Copy by Reference)
let userA = { score: 100 };
let userB = userA; // copies pointer
userB.score = 999;

console.log(userA.score); // 999 (altered!)
console.log(userB.score); // 999

๐Ÿ’ก Mental Model: Stack vs Heap Memory

โ€ข Primitives (Value Copy): Like photocopying a document. If you draw a smiley face on your copy (y), the original piece of paper (x) remains completely unchanged.
โ€ข Reference Types (Pointer Copy): Like sharing a Google Doc link. If anyone edits the document online (userB.score = 999), everyone with the link sees the modification immediately!

4. The typeof Operator

The typeof unary operator returns a string indicating the type of the unevaluated operand.

๐Ÿ“‹ JavaScript Data Types & typeof Quick Reference Scrollable Summary โ€ข 10 Types
Category Data Type typeof Return Examples & Literals Memory Storage
Primitive Number "number" 42, 3.14, NaN, Infinity Call Stack (Fixed 8 Bytes)
Primitive String "string" "Hello", 'JS', `Template` Call Stack (Immutable)
Primitive Boolean "boolean" true, false Call Stack (1 Byte)
Primitive Undefined "undefined" undefined Call Stack
Primitive Null "object" (Legacy Bug) null Call Stack
Primitive BigInt "bigint" 9007199254740991n, 100n Call Stack (Arbitrary Size)
Primitive Symbol "symbol" Symbol("id"), Symbol.for("key") Call Stack (Unique Token)
Reference Object "object" { name: "Alex", score: 100 } Heap (Stack holds pointer)
Reference Array "object" [1, 2, 3], ["A", "B"] Heap (Specialized Object)
Reference Function "function" function() {}, () => {} Heap (Callable Object)
โšก Quick typeof Explorer
typeof โž” "object"
๐Ÿ’ก In JavaScript, Arrays are specialized Objects with numeric keys.

5. The typeof null Quirk (Interview Classic)

โš ๏ธ The 1995 Legacy Bug: typeof null === "object"

typeof null returns "object". This is a famous bug from the first release of JavaScript in 1995. In the original C-based JavaScript engine, values were represented with type tags stored in the lowest bits. Object type tags were 000. Since null was represented as the NULL pointer (0x00), its type tag was 000, causing typeof to wrongly return "object".

How to correctly check for null?
const isNull = (val) => val === null; // โœ… Strict equality

6. Special Numbers: NaN, Infinity, and -Infinity

JavaScript includes three special numeric values within the number data type:

01

NaN

"Not-a-Number". Produced by invalid math operations (e.g. 0 / 0, "abc" * 2, Math.sqrt(-1)).

02

Infinity

Positive infinite limit. Produced when a calculation exceeds the maximum limit (e.g. 1 / 0, 1e308 * 2).

03

-Infinity

Negative infinite limit. Produced by dividing negative numbers by zero (e.g. -1 / 0, -Infinity).

Why NaN is unique in JavaScript:

NaN is the only value in JavaScript that is not equal to itself:

console.log(NaN === NaN); // false โŒ

// How to reliably check for NaN:
console.log(Number.isNaN(NaN));      // true โœ… (Strict, reliable)
console.log(Object.is(NaN, NaN));    // true โœ… (ES6 SameValue equality)

// โš ๏ธ Warning: The global isNaN() coerces values before checking:
console.log(isNaN("hello"));         // true (coerces "hello" -> NaN)
console.log(Number.isNaN("hello"));  // false (does NOT coerce, strictly checks)
Output
false
true
true
true
false

7. Type Conversion: Explicit vs Implicit Coercion

Type conversion converts a value from one data type to another. It occurs in two ways:

A. Explicit Type Conversion (Intentional & Predictable)

Developers manually convert types using built-in wrapper functions:

01

String Conversion: String(val)

Converts any value directly into its textual string representation:

String(123);       // "123"
String(true);      // "true"
String(null);      // "null"
String(undefined); // "undefined"
String([1, 2]);    // "1,2"
02

Number Conversion: Number(val)

Parses numeric values. Empty strings become 0; undefined becomes NaN:

Number("42");      // 42
Number("  123  "); // 123
Number("");        // 0
Number("abc");     // NaN
Number(true);      // 1 (false -> 0)
Number(null);      // 0 (undefined -> NaN)
03

Boolean Conversion: Boolean(val)

Evaluates truthiness. Only the 8 falsy values convert to false:

Boolean(1);        // true (0 -> false)
Boolean("Hello");  // true ("" -> false)
Boolean([]);       // true (objects truthy)
Boolean({});       // true
Boolean(null);     // false
Boolean(undefined);// false

B. Implicit Coercion (Automatic Runtime Coercion)

JavaScript automatically converts types behind the scenes when operators encounter mismatched types:

01

Plus (+) Operator (String Bias)

If any operand is a string, + performs string concatenation:

"5" + 2;         // "52"
1 + "2" + 3;     // "123"
1 + 2 + "3";     // "33" (1+2=3, "3"+"3"="33")
"Hi " + true;    // "Hi true"
02

Math Operators (-, *, /, %)

Arithmetic operators strictly coerce string operands into Numbers:

"5" - 2;         // 3
"10" * "2";      // 20
"10" / "2";      // 5
"abc" - 2;       // NaN
03

Equality Comparison (== vs ===)

== coerces types before checking; === requires matching type & value:

5 == "5";          // true (coerced)
5 === "5";         // false (different types)
null == undefined; // true (spec exception)
null === undefined;// false
๐Ÿงช Interactive Coercion Lab (Predict & Observe)
Interactive Matrix

Click each expression to see how the JavaScript engine converts operands step-by-step:

"5" + 2 โž” "52" (string)
Engine Breakdown:
1. Left operand is a string ("5").
2. Binary + operator sees a string and invokes ToString(2) โž” "2".
3. Concatenates "5" + "2" โž” "52".

8. Truthy and Falsy Values

In JavaScript, every value is inherently either truthy or falsy when evaluated inside a boolean context (such as an if condition, logical operator, or Boolean() call).

๐ŸŒŸ The Golden Rule of Truthy & Falsy

There are only 8 exact falsy values in JavaScript. Everything else without exception is TRUTHY (including empty objects {}, empty arrays [], and negative numbers like -1)!

Falsy Value Type Description
falseBooleanThe boolean literal false
0NumberThe number zero
-0NumberNegative zero
0nBigIntBigInt zero
"", '', ``StringEmpty strings (zero characters)
nullNullThe null primitive
undefinedUndefinedThe undefined primitive
NaNNumberNot-a-Number
โš–๏ธ Truthy / Falsy Interactive Tester
Logic Inspector

Test common tricky values to see whether JavaScript treats them as Truthy or Falsy:

[] Truthy
Boolean([]) === true
Why? All objects (including empty arrays [] and empty objects {}) are Truthy in JavaScript because they point to an allocated memory address.

9. Mutability: Primitives vs Objects

Understanding mutability prevents accidental state corruption bugs:

  • Primitives are Immutable: Once a primitive value is created in memory, its character sequence or numeric value can never be altered. String methods like .toUpperCase() or .trim() return a brand-new string; they never modify the original.
  • Objects are Mutable: Object keys and array elements can be added, updated, or deleted in place without changing the memory reference address.
// Primitive Immutability
let word = "hello";
word[0] = "H"; // Silently fails (or throws in strict mode)
console.log(word); // "hello" (Unchanged!)

let upperWord = word.toUpperCase(); // Creates a brand-new string
console.log(word);      // "hello" (Original intact)
console.log(upperWord); // "HELLO"

// Object Mutability
const user = { name: "Alex" };
user.name = "Sam"; // Mutates object in place
user.role = "Admin";
console.log(user); // { name: 'Sam', role: 'Admin' }

10. ๐ŸŽฏ Placement & Interview Quiz (8 Output Traps)

Test your mastery of data types, coercion, and evaluation traps commonly asked in technical screening interviews. Answer each question one by one:

๐ŸŽฏ Data Types Interview Deck
Question 1 of 8
โญ Easy โ€ข Interview Classic typeof Quirks
console.log(typeof null);
What will be printed to the console?
A) "null"
B) "object"
C) "undefined"
D) TypeError
โญ Easy โ€ข Special Numbers NaN Equality
console.log(NaN === NaN);
What will be printed to the console?
A) true
B) false
C) undefined
D) TypeError
โšก Medium โ€ข Tricky Definition typeof NaN
console.log(typeof NaN);
What will be printed to the console?
A) "number"
B) "NaN"
C) "undefined"
D) "object"
๐Ÿ”ฅ Hard โ€ข Relational Coercion Chained Operators
console.log(1 < 2 < 3);
console.log(3 > 2 > 1);
What will be printed to the console?
A) true then true
B) false then false
C) true then false
D) false then true
โšก Medium โ€ข Truthy Arrays Truthy vs Falsy
console.log(Boolean([]));
What will be printed to the console?
A) true
B) false
C) undefined
D) 0
โญ Easy โ€ข String Coercion Plus Coercion
console.log("5" + 2);
What will be printed to the console?
A) 7
B) "52"
C) NaN
D) TypeError
โญ Easy โ€ข Number Coercion Minus Coercion
console.log("5" - 2);
What will be printed to the console?
A) 3
B) "3"
C) NaN
D) "52"
๐Ÿ”ฅ Hard โ€ข Reference Mutation Heap References
const a = { score: 10 };
const b = a;
b.score = 99;

console.log(a.score);
What will be printed to the console?
A) 10
B) undefined
C) 99
D) TypeError

11. Common Data Type Mistakes & How to Avoid Them

01

Using == Instead of ===

5 == "5" allows hidden implicit coercion. Always use === for type-safe comparisons.

02

Assuming isNaN() is Safe

Global isNaN("hello") returns true even though "hello" is a string. Use Number.isNaN() instead.

03

Checking typeof null === "null"

typeof null returns "object". Always check with val === null.

04

Assuming Empty Arrays are Falsy

Boolean([]) is true! To check if an array is empty, check arr.length === 0.

12. Quick Revision Reference Table

Type Name Category typeof Output Memory Location Example Literals
numberPrimitive"number"Call Stack42, 3.14, NaN, Infinity
stringPrimitive"string"Call Stack"Hello", 'world'
booleanPrimitive"boolean"Call Stacktrue, false
undefinedPrimitive"undefined"Call Stackundefined
nullPrimitive"object" โš ๏ธCall Stacknull
bigintPrimitive"bigint"Call Stack100n, 9007199254740991n
symbolPrimitive"symbol"Call StackSymbol('id')
objectReference"object"Heap Memory{ a: 1 }, [1, 2]
functionReference"function"Heap Memory() => {}, function() {}

13. Interactive Practice Challenge

๐ŸŽฏ Coding Challenge: Robust Type Analyzer

Write a function analyzeValue(val) that takes any value and correctly returns:
โ€ข "null" if the value is null (bypassing the typeof bug)
โ€ข "NaN" if the value is NaN
โ€ข "array" if the value is an Array
โ€ข Otherwise returns standard typeof val

Your output will appear here.