This translation is incomplete. Please help translate this article from English.
局所変数を宣言します。任意で値を代入して初期化できます。
構文
let 宣言:
let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];
let 式:
let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) expression;
let 文:
let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) statement;
引数
| 引数 | 説明 |
|---|---|
var1, var2, …, varN |
変数の名前。任意の有効な識別子を指定できます。 |
value1, value2, …, valueN |
変数の初期値。任意の有効な式を指定できます。 |
expression |
任意の有効な 式 |
statement |
任意の有効な 文 |
説明
let を使用することで、変数のスコープをそれが使用されたブロック、文または式に限定することができます。
これは var (ブロックスコープに関係なく、グローバルな、もしくはある関数全体でのローカルな変数を定義する)とは異なります。
ブロックスコープ
let で宣言された変数はそれを取り囲んでいるブロックの先頭へ引き上げられます。
同じブロック内で同じ変数を再宣言すると TypeError が発生します。
if (x) {
let foo;
let foo; // TypeError が発生
}
しかし、関数の本体ではこの制限はありません!
function do_something() {
let foo;
let foo; // これは正常に動作します
}
警告: ECMAScript 6 草案(2012年4月時点)ではこの動作を不正なものとしています。つまり、未来のバージョンの JavaScript では首尾一貫して
TypeError が発生するでしょう。もしあなたがこれをしているとしたら、その悪習は避けるべきです。switch 文を使用する際、そこには1つしかブロックが無いため、例外を発生させてしまうかもしれません。
switch (x) {
case 0:
let foo;
break;
case 1:
let foo; // 再宣言による TypeError
break;
}
例
let 式 で宣言された変数は、その式の中でのみ有効です。
var a = 5; let(a = 6) alert(a); // 6 alert(a); // 5
ブロック内で使用されると、 let で宣言された変数はそのブロック内でのみ有効となります。 var で宣言された変数が宣言された関数内で有効となることとの違いに注意して下さい。
var a = 5;
var b = 10;
if (a === 5) {
let a = 4; // 変数aはifブロック内で有効
var b = 1; // 変数bはfunction内で有効
console.log(a); // 4
console.log(b); // 1
}
console.log(a); // 5
console.log(b); // 1
ループにおいて、var で定義されたグローバル変数を使う代わりに、let キーワードによってループ内でのローカル変数を使用することができます。
for (let i = 0; i<10; i++) {
alert(i); // 1, 2, 3, 4 ... 9
}
alert(i); // i は未定義
コンストラクタを仕様する際に let 文を用いることで、クロージャを使用せずにprivateなインターフェースを作成することができます。
/*\
|*|
|*| :: 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();