Variables & types.
The atoms of every program.
Before you can write loops, functions, or anything interactive, you need to understand how JavaScript stores and manipulates data. This lesson covers the three ways to declare a variable, the six data types you'll actually use, and the coercion rules that trip up every beginner.
Declare variables with const by default, let when you need to reassign, never var. The six types you'll use: string, number, boolean, null, undefined, and object (which includes arrays). Use === for comparison, never ==. The single biggest source of JavaScript bugs is type coercion — == and mixed-type operations silently convert values.
Before this lesson: complete Lesson 1 so you can run JavaScript in the browser console.
📝 Declaring variables
Three keywords. Use one by default, one when needed, never the third.
// const — the value can't be reassigned const name = "Alice"; const PI = 3.14159; // let — the value CAN be reassigned let score = 0; score = score + 10; // var — the OLD way, never use in new code var legacy = "don't use this";
const
The default. A binding that can't be reassigned. Use it for anything that doesn't change. Trying to reassign throws a TypeError.
let
For values that change. Loop counters, accumulators, state that updates. Reassignable and block-scoped.
var
Never use. Function-scoped, hoisted, can be redeclared. Source of bugs that let/const eliminate.
Naming rules
Letters, digits, $`, and _. Can't start with a digit. Case-sensitive. Use camelCase: firstName, not first_name.
Why const more than let? const tells readers "this value never changes" — which eliminates a whole class of bugs. Use const by default. Change to let only when you get an error.
🔢 The primitive types
Six types cover 99% of what you'll write. JavaScript has no int/float distinction.
// String
const single = 'hello';
const double = "world";
const backtick = template literal;
// Number — both integers and floats, one type
const age = 30;
const price = 19.99;
// Boolean
const isActive = true;
const isDeleted = false;
// null — intentionally empty
const empty = null;
// undefined — declared but not assigned
let notAssigned;
console.log(notAssigned); // undefined
// Object — arrays, functions, dates, etc.
const user = { name: "Alice", age: 30 };
const list = [1, 2, 3];
// Check the type with typeof
console.log(typeof "hello"); // "string"
console.log(typeof 42); // "number"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object" — famous JS bug
console.log(typeof []); // "object"
console.log(typeof function(){}); // "function"
Two famous typeof bugs. typeof null returns "object" — a bug from 1995 that can't be fixed. typeof [] also returns "object" — because arrays are objects. To check for null, use x === null. To check for arrays, use Array.isArray(x).
📋 Arrays — ordered lists
Store multiple values in order. Index by position. Iterate with loops.
// Create an array
const fruits = ["apple", "banana", "cherry"];
// Access by index (zero-based)
console.log(fruits[0]); // "apple"
console.log(fruits.length); // 3
// Modify
fruits[1] = "blueberry";
fruits.push("date");
fruits.pop();
// The three methods you'll use most
const nums = [1, 2, 3, 4, 5];
// map — transform each item
const doubled = nums.map(n => n * 2); // [2, 4, 6, 8, 10]
// filter — keep items that pass a test
const evens = nums.filter(n => n % 2 === 0); // [2, 4]
// reduce — combine all items into one value
const sum = nums.reduce((a, b) => a + b, 0); // 15
The .map() callback gotcha. [1,2,3].map(x => { x * 2 }) returns [undefined, undefined, undefined]. The curly braces create a block, not an expression. Fix: [1,2,3].map(x => x * 2) (no braces) or [1,2,3].map(x => { return x * 2; }) (explicit return).
🗂️ Objects — named key-value pairs
When data has a fixed shape and named fields, use an object.
// Create an object
const user = {
name: "Alice",
age: 30,
email: "alice@example.com",
isActive: true,
};
// Access by dot notation
console.log(user.name); // "Alice"
// Access by bracket notation
console.log(user["name"]); // "Alice"
// Modify
user.age = 31;
user.city = "NYC";
delete user.isActive;
// Get all keys, values, or pairs
Object.keys(user);
Object.values(user);
Object.entries(user);
// Nested objects
const order = {
id: 1,
customer: {
name: "Bob",
address: { street: "123 Main St", city: "NYC" },
},
};
console.log(order.customer.address.city); // "NYC"
⚠️ Type coercion — the source of all bugs
JavaScript silently converts types. This is the weirdest part of the language.
// The + operator: string wins
console.log(1 + 2); // 3
console.log("1" + 2); // "12"
console.log(1 + "2"); // "12"
// Other operators: number wins
console.log("10" - 5); // 5
console.log("6" * "2"); // 12
// == does type coercion, === doesn't
console.log(5 == "5"); // true
console.log(5 === "5"); // false
console.log(0 == ""); // true
console.log(null == undefined); // true
console.log(null === undefined); // false
console.log([] == false); // true
console.log([] == 0); // true
Just use === everywhere. The only valid use of == is checking for both null and undefined in one shot: if (x == null) catches both. Everything else: use ===. This one rule eliminates 90% of coercion bugs.
Falsy values. Six values are falsy: false, 0, "" (empty string), null, undefined, and NaN. Everything else is truthy — including "0", [], and {}. This is why if (someArray) checks whether the array exists, not whether it's empty. Use array.length > 0 for that.
🏆 Challenge
Three tasks. Each one teaches a different data type.
Task 1 — User profile
Create an object called profile with these fields: name, age, email, and isActive. Then print it using a template literal, update the age, add a city key, and print how many keys it has.
Task 2 — Array operations
Create numbers = [3, 1, 4, 1, 5, 9, 2, 6]. Use .map() to square each item, .filter() to keep only evens, and .reduce() to sum them all. Print each result.
Task 3 — Coercion traps
In the console, predict each before running: 1 + "1", 1 - "1", "1" === 1, null === undefined, [] == false. If you can predict all five, you understand coercion.
⚠️ Common mistakes
The variable and type bugs that catch every beginner.
var hoists, is function-scoped, and can be redeclared. Use const or let. Never var.
"5" == 5 is true. 0 == "" is true. null == undefined is true. Use === everywhere.
const arr = [1,2,3]; arr.push(4) works. const prevents reassigning arr, not modifying its contents.
console.log(user + "!") prints [object Object]!. Use JSON.stringify(user) to see the whole object.
arr[0] on an empty array returns undefined. Check arr.length > 0 or use optional chaining: arr[0]?.name.
.map() creates a new array. If you're iterating for side effects, use .forEach().
const a = {x: 1}; const b = a; b.x = 2; — a.x is now 2. Use {...a} for a shallow copy.
typeof null is "object". typeof [] is "object". Use x === null and Array.isArray(x).
➡️ What's next
You understand data now. Next: making things happen with functions.
❓ Frequently asked questions
What is the difference between let, const, and var?
const for values that don't change. let for values that do. var is the old way — never use it. const and let are block-scoped; var is function-scoped.
What are the primitive types in JavaScript?
Seven primitives: string, number, boolean, undefined, null, symbol, bigint. Plus one non-primitive: object (arrays, functions, dates).
What is type coercion?
JavaScript's automatic conversion of values between types. 1 + '1' gives '11'. 1 - '1' gives 0. '5' == 5 is true. Use === to avoid surprises.
What is the difference between == and =?
coerces types before comparing. === doesn't. '5' == 5 is true; '5' === 5 is false. Use === everywhere except x == null for checking both null and undefined.
How do I check the type of a variable?
Use typeof for strings, numbers, booleans, functions, and undefined. For null use x === null. For arrays use Array.isArray(x). typeof null and typeof [] both return "object" — bugs to remember.
What is the difference between an array and an object?
Arrays are ordered, indexed by number, with methods like .map() and .filter(). Objects are key-value pairs, indexed by string, for named data. Use arrays for lists, objects for records.
What is a template literal?
A string in backticks that supports ${expression} interpolation and multi-line content. const name = "Alice"; console.log(Hello, ${name}!`); prints "Hello, Alice!".
What is the difference between null and undefined?
undefined means "not yet assigned" — the default. null means "intentionally empty" — you set it yourself. Never assign undefined yourself; use null when a value is deliberately absent.