Values and variables

Declare variables correctly and know what each primitive type is for.

02of 32
≈ 11Min read
7Parts

const, let — and not var

  • Default to const. Reach for let only when you genuinely reassign the binding.
  • Both are block scoped: they exist only inside the nearest { }.
  • var is function scoped and hoisted to the top of the function as undefined, which produces bugs that read like magic.
the whole decision
const rate = 0.18;     // cannot be reassigned
let total = 0;         // will be reassigned
total += 100;

var old = 1;           // function scoped, hoisted — do not use it
const is not frozen

const stops the binding being reassigned, not the value being changed. const list = []; list.push(1) is fine. list = [] is not.

The temporal dead zone

let and const are hoisted too, but they stay uninitialised until the declaration runs. That gap is the temporal dead zone, and the error it throws is far better than silently getting undefined.

what hoisting really means
console.log(a);   // undefined — var is hoisted and initialised to undefined
var a = 1;

console.log(b);   // ReferenceError: Cannot access 'b' before initialization
let b = 1;

The seven primitives

Everything that is not a primitive is an object — including arrays, functions, dates and regular expressions.

TypeExampleFor
string"Painted"Text. Immutable — every "change" makes a new one.
number5, 1.5, -0.2All numbers. There is no separate integer type.
booleantrue, falseTwo values.
nullnullDeliberately empty. You set it.
undefinedundefinedNot set. The language sets it.
bigint9007199254740993nIntegers beyond 2^53. Rare.
symbolSymbol("id")A unique key. Rarer still.

null versus undefined

Use null when you are saying "there is deliberately no value here". Leave undefined to the language.

they mean different things
let a;                    // undefined — declared, never assigned
const b = null;           // null — deliberately nothing

obj.missing;              // undefined — no such property
fn();                     // undefined — a function with no return

typeof undefined;         // "undefined"
typeof null;              // "object"  ← a bug from 1995, never fixable

Strings are immutable

Every string method returns a new string. If you do not keep the result, nothing happened — a mistake that silently does nothing, which is the hardest kind to see.

nothing is changed in place
let name = "painted";
name.toUpperCase();        // "PAINTED" — returned, not stored
console.log(name);         // still "painted"

name = name.toUpperCase(); // now it is

Naming

  • camelCase for variables and functions, PascalCase for classes and components, SCREAMING_SNAKE for true constants.
  • Name a boolean so it reads as a question: isOpen, hasError, canEdit.
  • Name a function for what it does: formatPrice, not price.
  • Short names are fine for a short life: i in a loop, d in a one-line map. A variable that lives for thirty lines needs a real name.
The real test

If you have to read the assignment to know what a variable holds, the name is wrong.

Declaring in the right place

as late and as narrow as possible
// worse: one binding reused for two unrelated things
let value;
value = door.days;
// …forty lines…
value = user.name;

// better: two bindings, each where it is needed
const days = door.days;
// …
const name = user.name;

Practice