i
他の回答で既に述べたように、変数をで宣言しないため、コードは機能しませんvar
。これにより、自動的にグローバルになります。したがって、実際には関数とブロックのスコープの問題ではありません。を使用var
して変数を宣言すると、変数のスコープは、宣言がネストされた関数内に含まれる同じ関数に制限されます。関数内にない場合はグローバルになります。
ネストされた関数で同じ変数名を使用すると、内側のスコープの変数は外側のスコープを「隠す」と言われます。その場合、内部関数はその名前の外部関数の変数にアクセスできません。その名前を使用すると、独自の変数しか与えられないためです。いわば。ただし、グローバル変数をオブジェクトのプロパティとして扱うことでアクセスできwindow
ます。
「私が知りたいのは、そのような動作を維持する方法です。ブロック スコープのようなものを強制することを意味します。そうしないと、非常に厄介なバグが非常に簡単に作成されます...」
いいえ、正しく使い始めるvar
と、これらのバグを回避することは難しくありません。ただし、すぐに呼び出される無名関数を導入することで、ブロック スコープを強制できます。
(function() {
// variables created in this function are accessible
// only within this function
var x, y, z;
})();
console.log(typeof x); // "undefined" (x can't be seen from outside the function)
function(){}
関数が関数ステートメントではなく式として解釈されるように、かっこで囲む必要があります。最後の余分な()
機能は、その関数式がすぐに実行されるようにすることです。この構造の一般的な用途は、スクリプト全体をその中に囲むことです。これにより、変数や関数がグローバルにならず、他の JS インクルード ファイルからロードされた他のスクリプトと相互作用しなくなります。(ブロック内で宣言されている複数の関数間で共有されるブロック内に疑似グローバル変数を含めることができます。)
たとえば、for
ステートメントの本文をスコープ付きの「ブロック」にしたい場合は、次のようにします。
for (var i = 0; i < something; i++) {
(function() {
var x = i;
// do something with x
})();
}