var
ループヘッダーでwith を宣言することの問題は、それが欺瞞的であることです。スコープがループに限定されている変数を宣言しているように見えますが、宣言の前for
を含め、実際には関数内のどこにでも存在します。
var i = 1;
function foo() {
console.log(i); // 'undefined'
for (var i=1; i<100; ++i) {
}
}
console.log
呼び出しは local の宣言の前に発生しますがi
、同じ関数内にあるため、まだスコープ内にあります。i
そのため、まだ値が割り当てられていないlocalが に渡されlog
ます。これは驚くべきことです。Javascript のスコープ ルールに慣れていない人にとっては、これは明らかなことではありません。
ECMAScript 2015から、変数を宣言するより良い方法があります: let
. で宣言された変数はlet
、関数全体ではなく、それらを含むブロックに対してローカルです。したがって、上記のコードのこのバージョンは1
意図したとおりに出力されます。
let i=1; // could use var here; no practical difference at outermost scope
function foo() {
console.log(i); // 1
for (let i=1; i<100; ++i) {
}
}
したがって、最新の Javascript でのベスト プラクティスは、変数をlet
ではなく で宣言することですvar
。ただし、ECMAScript 2015 より前の実装に行き詰まっている場合は、最初に使用するまで待つのではなく、関数の先頭ですべての変数を宣言する方が少し混乱が少なくなります。