tl;dr my opinion 🤔💭: use const
by default, only use let
if required.
History
JavaScript has three* ways to declare variables:
var x = 123;
let y = 456;
const z = 789;
The first, var
, comes from the original version of JavaScript. The later two arrived widely across browsers in about 2016.
Constant by Default
If you declare variables with const
, they cannot be changed ("mutated"). (If the variable points to an object, you can mutate the object.) For example:
const value = 123;
const object = {abc: 123};
object.abc++; // ok ✅
value++; // error ❌
object = null; // error ❌
This is an extremely primitive but useful method of safety while building JS. If a variable isn't meant to be mutated—it's the result of some complex operation—then const
means you can't accidentally use it incorrectly. (This is also useful in conjunction with strict mode, where you can't just invent variable names without var
, let
or const
). 🔬
Let On Demand
If you later find out that you need a variable to mutate, you can go back to its declaration and mark it as let
. This lets readers of your program know a bit more about the variable.
const counter = getTotalEvents();
// ...later, we decide to add something, but this will 💥
counter += otherEvents();
If we modify const counter
to be let counter
, readers will know that it's not the final value: it will likely mutate further on below.
Gotchas
- Function arguments are always mutable.
function foo(foobar) {
++foobar;
return foobar;
}
- You can and should use
const
inside afor-of
orfor-in
loop (which is not always obvious, since it seems like the variable is mutating every iteration). 🤔
for (const x in object) { ... }
for (const x of arrayOrIterable) { ... }
Var Considered Confusing
Declaring with var
has some quirks—the variable declaration is hoisted to the top of a function, so it's always available. Here's an example, but showing that you could just use let
instead:
Declaring with var
can be useful in some occasions, but I believe it does not follow the principle of least surprise, and you can always replace it with let
.
The Exception*
Function declarations are technically another way to declare a variable.
function foo() {
// do stuff
}
// "foo" is now something we can pass around, e.g.:
setTimeout(foo, 1000);
This isn't exactly like saying var foo = function() { ... }
, but it's similar. The main difference being that the declaration itself is hoisted, not just the variable name. Here's that in action:
foo(); // ok! ✅
bar(); // crashes: "bar" is a valid name, but contains undefined 😕
function foo() {}
var bar = function bar() {};
Function declarations are a useful concept in JS, because it lets us pass around functions before they are declared—allowing for circular 🔄 references such as passing functions as callbacks. (If you're curious, I talk about how this interacts with ES6 modules in a talk 🗣️💬 I gave at the Polymer Summit in 2017).
Thanks!
That's all for today, just a simple opinion piece!
5 👋
I disagree regarding const. Spamming the keyword inflates it's meaning to me. I believe you should only use it when you actively intend a variable to be unchangeable - because otherwise when reading another person's code I would conclude you just used the keyword without thought and disregard const as a whole.
I do agree with the rest of your post in general though. Instead of using constants as a default, I'd recommend to rather put thought into your code before deciding which keyword to use.
But to quote you, this is just my opinion piece 😉