The completion of ES6 in 2015 brought new ways to define JavaScript variables. The let
keyword creates a variable with a block scope while const
specifies an immutable value. Here’s the lowdown on how these modern variable types differ from the classic var
True
Prior to ES6, var
was your only option when defining a variable. You can freely change the values of variables created with var
You can also re-declare the variable itself.
var demo = "first value"; var demo = "second value"; demo = "third value"; example = "this throws an error - variable not declared";
Using var
creates a variable targeting the current function. When used outside of a function, the resulting variable has global scope.
The “scope” of a variable describes where it can be used. A variable with a function scope is accessible via code in the function that defines it. A global variable can be accessed anywhere in your code.
var myGlobal = "global"; function testA() { var myFunctionScope = "testA"; console.log(myFunctionScope); console.log(myGlobal); } function testB() { myGlobal = "overwritten!"; console.log(myGlobal); // console.log(myFunctionScope); // ERROR } testA(); testB(); testA();
This example shows the difference between variables with a global scope and variables with a function scope. myGlobal
can be read (and written) by both testA
and testB
myFunctionScope
is only defined in testA
, So testB
throws an error when trying to access it. Here’s what this example would yield:
testA global overwritten! testA overwritten!
The value of myFunctionScope
is maintained separately within each function. The value of myGlobal
will be updated in both functions when testB
overwrites it.
Let
The newer let
keyword is the modern alternative to var
You can often adopt let
in all the places where you wrote var
However, there are important differences.
The most important let
characteristic is the range. Variables refer to individual blocks of code rather than complete functions. In JavaScript, a block is a portion of code enclosed in curly brackets. Each let
variable can only be accessed by code within its block.
function letTest(x) { let demo = "hello world"; if (x > 10) { let y = 9000; demo = "foobar"; } console.log(demo); // "foobar" console.log(y); // ERROR }
In this example, the if
statement creates a new code block. Blocks inherit the range of their parent block, so the demo
variable remains available. The y
variable falls under the if
pronunciation. Trying to gain access y
outside of if
block results in an undefined variable error.
Like it var
, variables created with let
can have their values changed at any time. However, they cannot be indicated again – with let
twice with the same name in a single block will cause an error.
let demo = "test"; demo = "example"; let demo = "test"; // ERROR
An exception is re-declaring a variable in a nested range. Block-level scoping rules allow this – you get two divorce variables that happen to have the same identifier.
let foo = "bar"; if (true) { let foo = "foobar"; console.log(foo); } console.log(foo);
The above example would broadcast foobar bar
The foo
variable is re-declared in the if
block, without the foo
variable of the outer scope. You lose the ability to refer to the outer variable from the inner block.
Const
The const
keyword was another ES6 addition. It’s like a block range let
const
is short for “constant” and is used for fixed values that will never change. Tries the value of a const
variable will always result in an error.
const foo = "bar"; const foo = "foobar"; // ERROR
That’s why you should always initialize const
variables with a value. You are not allowed to use a const
and set the value later.
let demoLet; // OK var demoVar; // OK const demoConst; // ERROR const demoConst = "value"; // OK
Technically, const
does not define a constant value. It actually creates one constant reference to a value. The effect of this is that you can change the properties of objects assigned to a const
Errors only occur if you use the const
itself to the left of an assignment.
What type of variable should I use?
You should adopt let
for most common variables in your JavaScript code. The block-level scoping and forbidden re-declaration help to detect errors and prevent accidental overwrites.
Using let
stops variable “leak”, where variables are accessible in ranges they are not intended for. A classic example are iterators in loops:
for (var i = 0; i <= 10; i++) { // do something } console.log(i);
This would result in 10
is broadcast to the console. Using let
would broadcast instead undefined
, like the i
variable would be inaccessible outside of the if
Scope. This is usually the desired outcome in these types of scenarios.
Loops also show the dangers of var
relocation:
for (var i = 0; i <= 10; i++) { setTimeout(() => console.log(i), 1000); }
At first glance, this code looks like this should broadcast the numbers 1 to 10. 10
is logged ten times. setTimeout()
is asynchronous and i
in the callback is lexically bound to the scope. Like var i
is used in the loop, the i
variable gets a new value with each iteration. When the timer callback runs, all ten iterations have already been completed and i
will always resolve to the final value – 10
, in this case.
Using let i
instead, a new named variable i
for each iteration of the loop. Each variable retains its own value after iteration is complete, resulting in the expected log output.
When not to use Please
There are scenarios you shouldn’t use let
You should use const
when you create a variable that you know will never change. Bundlers and static analysis tools can then warn you if you inadvertently try to reassign its value.
It’s usually a good idea to keep variables immutable where possible. This helps eradicate bugs caused by accidental overwriting. Using const
also helps you state your intent in a codebase by making it explicit that a value does not change.
ES6 features such as let
and const
are now universally supported by modern browsers. Some older browsers without full ES6 support, especially Internet Explorer 11, also offer them. You don’t have to worry about whether they will be available unless you’re targeting a heavily outdated platform. Use let
and const
to keep your code cleaner and reduce the risk of hidden bugs.
Source link