Introduced in JavaScript 1.7
Summary
Declares a block scope local variable, optionally initializing it to a value.
Syntax
let definition:
let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];
let expression:
let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) expression;
let statement:
let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) statement;
Parameters
| Parameter | Description |
|---|---|
var1, var2, …, varN |
Variable name. It can be any legal identifier. |
value1, value2, …, valueN |
Initial value of the variable. It can be any legal expression. |
expression |
Any legal expression. |
statement |
Any legal statement. |
Description
let allows you to declare variables, limiting its scope to the block, statement, or expression on which it is used. This is unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope.
Block scoping
let declared variables are hoisted to the beginning of the enclosing block.
Redeclaration of the same variable in the same block scope raises a TypeError.
if (x) {
let foo;
let foo; // TypeError thrown.
}
However, function bodies do not have this limitation!
function do_something() {
let foo;
let foo; // This works fine.
}
TypeError if you do this, so you should avoid this practice!You may encounter errors in switch statements because there is only one underlying block.
switch (x) {
case 0:
let foo;
break;
case 1:
let foo; // TypeError for redeclaration.
break;
}
Examples
A let expression limits the scope of the declared variable to only that expression.
var a = 5; let(a = 6) alert(a); // 6 alert(a); // 5
Used inside a block, let limits the variable's scope to that block. Note the difference between var whose scope is inside the function where it is declared
var a = 5;
var b = 10;
if (a === 5) {
let a = 4; // The scope is inside the if-block
var b = 1; // The scope is inside the function
console.log(a); // 4
console.log(b); // 1
}
console.log(a); // 5
console.log(b); // 1
You can use the let keyword to bind variables locally in the scope of loops instead of using a global variable (defined using var) for that.
for (let i = 0; i<10; i++) {
alert(i); // 1, 2, 3, 4 ... 9
}
alert(i); // i is not defined
When you are dealing with constructors you can use the let statement in order to create a private interface without using closures:
/*\
|*|
|*| :: A public and reusable API for constructors ... ::
|*|
\*/
let (
switchScope = function (oOwner, fConstructor) {
return oOwner && oOwner.constructor === fConstructor ? oOwner : this;
}
) {
function buildIndoors (fConstructor) {
const oPrivate = new fConstructor(this);
this.getScope = oPrivate.getScope = switchScope.bind(this, oPrivate);
return oPrivate;
}
}
/*\
|*|
|*| :: Use of the *let* statement in order to create a private interface without closures... ::
|*|
\*/
let (
/* "Secrets" is the constructor of the private interface */
Secrets = function Secrets (oPublic /* (the public interface) */) {
/* setting a private property... */
this.password = Math.floor(Math.random() * 1e16).toString(36);
/* you can also store the public interface into a private property... */
/* this.publicInterface = oPublic; */
alert("I\'m getting a public property from a private constructor...: somePublicProperty: " + oPublic.somePublicProperty);
}
) {
/* "User" is the constructor of the public interface */
function User (sNick) {
/* setting a public property... */
this.somePublicProperty = "Hello World!";
const oPrivate = this.createScope(Secrets); /* (the private interface) */
/* setting a public property... */
this.user = sNick;
alert("I\'m getting a private property from a public constructor...: password: " + oPrivate.password);
}
User.prototype.somePublicMethod = function () {
const oPrivate = this.getScope(Secrets); /* (the private interface) */
alert("I\'m getting a public property from a public method...: user: " + this.user);
alert("I\'m getting a private property from a public method...: password: " + oPrivate.password);
oPrivate.somePrivateMethod();
};
Secrets.prototype.somePrivateMethod = function () {
const oPublic = this.getScope(); /* (the public interface) */
alert("I\'m getting a public property from a private method...: user: " + oPublic.user);
alert("I\'m getting a private property from a private method...: password: " + this.password);
};
/* ...creating a mutual access... */
User.prototype.createScope = buildIndoors;
}
/* out of the *let* statement you have not access to the private interface! */
const johnSmith = new User("John Smith");
johnSmith.somePublicMethod();
Mozilla Developer Network