Values and Types
The atoms of every JavaScript program — what values are, what types they have, and why this distinction matters.
Before you can write meaningful programs, you have to know what your programs are made of. The answer, at the bottom, is values. Programs create values, combine values, compare values, and move values around. Everything else is plumbing.
This page is the most fundamental of the whole course. Take your time with it.
A value is "a piece of information"
A value is a piece of information your program has at some moment. Some examples:
- The number
42. - The text
"hello". - The truth-value
true. - The "nothing here" marker
null. - A list of three things,
[1, 2, 3]. - A small record,
{ name: "Ada", age: 28 }.
A value, on its own, just is. It is the runtime's job to keep track of values, and your job as a programmer to decide what to do with them.
You can ask the runtime to print a value with console.log. The
runtime hands the value to console.log, which converts it to text
and displays it.
Each of these calls hands a value to console.log, which prints it
in a sensible way for its kind.
A type is "the kind of value"
Every value has a type — the kind of value it is. JavaScript
has a small set of built-in types, and you can ask the runtime
what type any value has with the typeof operator:
The output tells us JavaScript's main types are:
| Type | What it represents | Example values |
|---|---|---|
number | All numbers, integers and decimals alike | 0, 42, -7, 3.14, -0.001 |
string | Text | "hello", 'world', `hi ${name}` |
boolean | Truth values | true, false |
undefined | "no value yet" | undefined |
null | "deliberately empty" | null |
object | Composite values (records, arrays, dates, etc.) | {}, [], new Date() |
function | Things you can call | function(){}, x => x + 1 |
symbol | A unique label (advanced) | Symbol("id") |
bigint | Arbitrary-precision integers (advanced) | 42n, 9999999999999999n |
For most of this course, the first six are all that matter. We will meet symbols and bigints much later, if at all.
Why does typeof null say "object"?
This is one of JavaScript's oldest, most famous bugs. In the very
first implementation in 1995, the way null was represented under
the hood happened to look like an object, and typeof reported
"object". By the time anyone wanted to fix it, fixing it would
have broken too many web pages. So it stays — forever.
If you ever need to check for null specifically, write
value === null.
Primitive vs object types
The types divide into two large families:
- Primitive types:
number,string,boolean,undefined,null,symbol,bigint. These are simple values: small, copied by value, and immutable. - Object types: arrays, plain objects, functions, dates, and more. These are composite values: they have parts, they live in the heap, and they are referred to by reference.
We will spend the next several pages on the primitives, then build up to objects later.
What "immutable" means for primitives
When we say a primitive is immutable, we mean: the value itself
cannot be changed. The number 5 will always be the number 5.
The string "hello" will always be the string "hello". You
cannot reach inside 5 and turn it into 6.
You can, of course, replace the value stored in a variable. But that does not change the old value; it just makes the variable point to a new one.
This sounds like a pedantic distinction. It will matter enormously later, when we get to objects, which behave the opposite way: objects can be modified in place, and that has consequences.
Conversions: when types meet
JavaScript will frequently convert a value from one type to another, sometimes silently. This is one of the most surprising parts of the language for beginners.
There are two kinds of conversion:
- Implicit conversion: JavaScript decides, behind your back. Most of the surprising examples above use implicit conversion.
- Explicit conversion: you ask for the conversion using a
built-in function or operator:
Number("42"),String(42),Boolean(0), etc.
The single best piece of advice on this topic: always be
explicit. If you mean "treat this string as a number", say
Number(text). Don't rely on subtraction silently doing it. Your
future self will thank you when you read the code six months later
and don't have to ask "why does this work?".
Comparing values: == vs ===
JavaScript has two equality operators:
===(strict equality) — compares values and requires the same type.5 === "5"isfalse.==(loose equality) — converts as needed before comparing.5 == "5"istrue.
Always use === (and its partner !==). Loose equality is
full of historical surprises (null == undefined is true, but
null == 0 is false; the rules are an ancient swamp). Strict
equality is predictable.
null vs undefined
These two look similar but have slightly different intent:
undefinedmeans "no value has been assigned". JavaScript itself gives youundefinedin many situations: a variable declared but never set, a function parameter that wasn't passed, a property that doesn't exist on an object.nullmeans "a value of nothing was deliberately put here". When you the programmer want to mark "this slot is intentionally empty", you writenull.
In practice many codebases use one or the other consistently; either is fine, as long as you are deliberate.
"Truthy" and "falsy" values
JavaScript inherits, from its scripting roots, the idea that every
value can be treated as if it were a boolean. The values that
behave like false in conditions are called falsy; the rest are
truthy.
The falsy values are exactly these (memorise this list — it's short):
false0(and-0, and0n)""(empty string)nullundefinedNaN
Everything else is truthy. This includes "0", " ", [],
{}, and the string "false". They all behave as true in a
boolean context.
This is incredibly useful in practice — if (name) { ... } is a
common idiom for "if name is set to something non-empty". It can
also bite you (an empty array [] is truthy even though it
"feels" empty). We will see it constantly.
A multi-file taste of how values move around
In a real program, values are the things that flow between functions and files. Here is a small two-file example: one file defines a couple of pure functions that take values and return values, the other uses them.
Notice: every function takes a value (a number) and returns a value (another number, or a boolean, or a string). The functions have no idea where the input came from, and no idea what will happen to the output. They just transform values. This is the core mental model of programming.
Which equality operator should you almost always use in JavaScript, and why?
== because it is more forgiving and converts types automatically
=== because it compares values and types, giving predictable behaviour without surprising conversions
= because it is the assignment operator and works for everything
It doesn't matter — they behave identically