Syntax, Values & Types
A program shuffles values around - text, numbers, true/false - and needs to name them to refer to later. This phase covers both: the values JavaScript has, and how you name them. Most of JavaScript's famous "weird parts" live here, so we'll meet them head-on rather than let them ambush you.
Naming values: let and const
A variable is a name pointing at a value. Make one with let or const, an =, and the value:
let = 0;
const = ;
;
0 Ada
What just happened: let score = 0 created score pointing at 0; const name = "Ada" pointed
name at "Ada". The semicolon ; ends a statement - JavaScript is fairly relaxed about them, but
using them is a good habit that avoids a rare class of surprises.
One rule tells them apart:
let- reassignable. Use for values that change (a score, a counter, a running total).const- not reassignable. Use for values that shouldn't change. The one you'll use most.
let = 1;
count = 2; // fine - let allows this
const = 10;
limit = 20; // error - const forbids reassignment
TypeError: Assignment to constant variable.
What just happened: Reassigning count worked since it's a let; reassigning limit threw a
TypeError, because const means "this name will always point at this value" - a safety rail, not a
restriction to fight.
💡 Key point. Default to const; reach for let only when you genuinely need to reassign. Code
where most names are const is easier to reason about.
⚠️ Why not var? The original way to declare variables, with two traps let/const were designed
to fix: its scope leaks out of blocks in surprising ways, and it lets you redeclare the same name
silently. The community moved on years ago (2015, "ES2015"). Read var when you see it; don't write it.
The primitive types
Every value has a type that determines what it is and what you can do with it. The fundamental ("primitive") types you'll use constantly:
- string - text:
"hello",'also hello'. Single or double quotes work; pick one and stay consistent. - number - any number, whole or decimal:
42,3.14,-7. JavaScript has one number type, not separate integer and float types. - boolean -
trueorfalse, the answer to a yes/no question. - null - a deliberate "nothing here"; you set something to
nullto mean "intentionally empty." - undefined - "no value assigned yet," which JavaScript hands you automatically for a variable that exists but was never given a value.
You can ask any value its type with the typeof operator:
; // string
; // number
; // boolean
; // undefined
string
number
boolean
undefined
What just happened: typeof reports the type of the value to its right as a string - handy when you're
unsure what you're holding, especially for values from outside your control.
📝 Terminology - null vs undefined. Both mean "no real value," which confuses everyone at first:
undefined is the system's "you never set this"; null is your "I'm deliberately setting it to
empty." An unfilled search box might be "" (empty string); a setting you explicitly cleared might be
null; a variable you declared but didn't assign is undefined.
Template literals: building strings cleanly
You'll constantly want to mix text and values. The clean way uses template literals - strings wrapped
in backticks (`) instead of quotes, with ${...} holes you drop values into:
const = ;
const = 42;
;
Ada scored 42 points.
What just happened: Inside backticks, anything in ${...} gets evaluated and dropped into the string.
No fiddly + between pieces, no quote-juggling. Template literals also let a string span multiple lines
without tricks - once you meet them you'll rarely glue strings together any other way.
Dynamic and loose typing - the part to understand deeply
This is where JavaScript surprises people from other languages - two separate ideas that often get muddled.
Dynamic typing means a variable's type isn't fixed - it's decided by whatever value is in it right now, and it can change:
let = 42; // x holds a number
x = ; // perfectly legal - x now holds a string
What just happened: The same name x held a number, then a string. JavaScript never made you declare
a type; the value carries its own type, and the variable just points at whatever's there. Flexible, and
also a source of bugs - nothing stops a variable from quietly becoming a different kind of thing.
Loose typing means JavaScript automatically converts between types when an operation mixes them, unasked. The famous footgun:
; // string + number
; // string - number
51
4
What just happened: With +, JavaScript saw a string on the left, decided you must mean
concatenation, turned 1 into "1", and glued them: "51". With -, there's no string version of
subtraction, so it went the other way - turned "5" into the number 5 and subtracted: 4. Same two
values, opposite conversions, depending on the operator - loose typing in a nutshell.
⚠️ The gotchas everyone hits
== vs === - always use ===. JavaScript has two equality operators: == ("loose equality")
converts types before comparing, producing baffling results; === ("strict equality") compares without
converting - values must match in both value and type.
; // true ("" converts to the number 0)
; // false (number vs string - no conversion)
; // true ("1" converted to 1)
; // false (number vs string)
What just happened: == quietly converted types to find a match, producing surprises like 0 == ""
being true. === refused to convert, so a number and a string are never equal. Make it a habit: use
=== (and !==) everywhere. The only exception - checking for null/undefined together - you can
learn later.
NaN - "Not a Number," and it's contagious. When a math operation can't produce a real number, you
get NaN:
; // tried to make a number from non-numeric text
; // the famous one
NaN
false
What just happened: Number("hello") couldn't find a number in "hello", so it returned NaN. And
NaN === NaN is false - NaN is the only value not equal to itself, by design (it represents "an
invalid result," and two invalid results aren't meaningfully "the same"). To check for it, use
Number.isNaN(x), never x === NaN.
Floating-point money - don't store cents as decimals. JavaScript numbers can't represent every decimal exactly, the single most reported "JavaScript is broken" moment:
;
;
0.30000000000000004
false
What just happened: 0.1 and 0.2 can't be stored exactly in the binary format JavaScript uses for
numbers (true in almost every language, not a JavaScript flaw), so their sum is a hair off 0.3. The
fix: work in the smallest unit as whole numbers - store $1.30 as 130 cents, do math on integers,
divide by 100 only when displaying. Never compare prices with === on decimals.
Recap
constby default,letwhen you must reassign. Avoidvar- read it, don't write it.- Primitive types: string, number (one type for all numbers), boolean,
null(deliberate empty),undefined(never assigned). Check withtypeof. - Template literals (
`${value}`) are the clean way to mix text and values. - Dynamic typing: a variable's type follows its current value. Loose typing: operations auto-convert across types - sometimes helpfully, often confusingly.
- Always use
===, checkNaNwithNumber.isNaN, never trust===on decimal money - work in integer cents.
Next: collections of values - lists (arrays) and labeled bundles (objects).
← Phase 1: Install & Your First Program · Guide overview · Phase 3: Collections →
Before the quiz: without looking back, say (or jot down) the core idea of this phase in your own words.
Check your understanding 2 questions
1. Which variable keyword should you default to?
2. Why always use === instead of ==?