let, const, and Scope
Block scope, the temporal dead zone, and why var still causes surprises.
Every example here uses show data, because that is what the app will hold.
Three ways to declare a variable
const names a value you will not replace. let names one you will.
watched is now true, because let allows a new value.
Giving a const a new value is an error:
const title = "Severance";
title = "Andor";
// TypeError: Assignment to constant variable.
There is an older keyword, var. Avoid it in new code. The next section
shows why.
Block scope
A block is any pair of braces, such as the body of an if. let and const
live inside that block. var ignores the braces and can be read afterwards.
era is still readable after the if, which is rarely what you meant.
Reading label there throws, because that name only exists inside the block.
The temporal dead zone
A let or const name exists from the start of its block. You cannot read it
until its declaration runs. That gap is the temporal dead zone. Reading the
name inside it throws.
var is different: it starts as undefined, so an early read gives you a
confusing value instead of an error.
console.log(year); // undefined — var starts as undefined
console.log(title); // ReferenceError: Cannot access 'title' before initialization
var year = 2022;
let title = "Severance";
The error is the better behaviour. It points at the line with the problem. An
undefined would travel on and break somewhere else.
This one is not a sandbox on purpose. The editors here rewrite let to var
before running your code, which removes the dead zone. Run it in your own
browser console to see the real error.
const is not immutability
const protects the name, not the value. You cannot point the name at another
object, but you can change the object it already points at.
The log reads Severance 2022. The object changed, even though show is a
const.
What you cannot do is give show a different object:
const show = { title: "Severance", year: 2021 };
show = { title: "Andor", year: 2022 };
// TypeError: Assignment to constant variable.
Changing an object in place causes bugs later. Most code copies it instead. Destructuring, Spread, and Rest shows how.
Truthy, falsy, and a fallback
|| and ?? both fill in a missing value. They disagree about what missing
means.
|| hides the real rating of 0. ?? keeps the 0. It also keeps the empty
network name, so that line is blank.
|| falls back on any falsy value. Six values are falsy: false, 0, "",
null, undefined, and NaN. Everything else is truthy.
?? falls back only on null and undefined. Use it for a number that can
be 0. Use || when an empty string should count as missing.
Common mistakes
- Reaching for
letfirst. Start withconst, and change it only when you give the name a new value. - Expecting
constto freeze an object. It does not; the fields can still change. - Using
||for a rating. A real0is falsy, so||hides it. Use??.
Exercise
The line below should print the real rating. Andor has a rating of 0, so
the console should read:
Rating: 0
It prints Rating: not rated instead. Change one operator.