JavaScript の変数はすべて関数オブジェクトの開始時に生成される
function f() { // この時点で変数 a は生成されている a = 1; var a; alert(a); // 1 };
たとえ、関数中にブロックがあろうとも
function f() { // この時点で変数 a は生成されている { a = 1 } { var a } alert(a); // 1 }
たとえ、with スコープがあろうとも
function f() { // この時点で変数 a は生成されている a = 1; var b = {}; with(b) { var a; // この var は直近の with スコープではなく、 // 関数スコープに対する var となる a = 2; } alert(a); // 2 }
with スコープでは、変数を動的に追加することができる
function f() { // この時点で変数 a は生成されている var a; var scope = {}; with(scope) { a = 1; // 関数スコープの a scope.a = undefined; a = 2; // with スコープの a alert(a); // 2 } alert(a); // 1 }
関数スコープに、動的に変数を生成することはできないのか
今までは、僕も以下の理由で出来ないと思っていた。
- 変数は関数の一番最初に生成される。
- 関数スコープに関数を生成する方法は var 宣言しかない。
しかし、方法があった。
eval を使うとできるみたい
var a; function f() { a = 1; eval('var a'); a = 2; alert(a); // 2 alert(window.a); // 1 }
おおおおおおおお!できた!
これを使うと
以下のように、グローバル変数を使えない関数を作ったりできます。
var sandbox = (function() { var a = []; for (var n in window) a.push(n); eval('var ' + a.join(',')); return function() { alert(); // Error: alert is not a function; }; })();
役に立つかと言われれば疑問ですがw