変数は、クロージャーに対して「グローバル」にすることはできません。
それはグローバルかそうでないかのどちらかです。
そうでない場合は、関数スコープ内にあります。
それが関数のスコープ内にある場合、その関数の外にいるときにそれを取得する唯一の方法は、関数から返すプロパティにするか、オブジェクト/配列に追加することです。関数に渡されるか、その変数を返す関数の INSIDE を作成します...
// modifying an object
var my_func = function (obj) {
var hidden = 1;
obj.hidden = hidden;
};
var my_obj = {};
my_func(my_obj);
my_obj.hidden; // 1
// returning a function
var my_func = function () {
var a = 1,
b = 2,
c = 3,
get_a = function () { return a; },
get_b = function () { return b; },
get_c = function () { return c; };
return { a : get_a, b : get_b, c : get_c };
};
var my_obj = my_func();
my_obj.a(); // 1
my_obj.b(); // 2
my_obj.c(); // 3
これを「名前」で行いたい場合は、クロージャに 1 つのオブジェクトを作成し、文字列を取り、そのオブジェクトのプロパティを名前で検索する関数を作成します。
// get property by name
var my_func = function () {
var properties = {
a : 1,
b : 2,
c : 3
};
return {
get : function (name) {
return properties[name]; // returns undefined if it doesn't exist
}
};
};
var my_obj = my_func();
my_obj.get("a"); // 1
my_obj.get("b"); // 2
今すぐできます。
PS:eval();
上記の方法で動作することが常に保証されているわけではありません。
たとえば、将来的にeval
は、独自のスコープで実行し、呼び出し元の関数のスコープにはアクセスできません (ビルドと同じようにnew Function("...");
)。
編集
"global"
これをさらに一歩進めて、スコープに関連する 質問に適切に答えるには、次のようにします。
window.bob = "Bob";
var outer_A = function () {
var mid_A = function () {
var inner_A = function () {
console.log("INNER-A");
console.log("bob = " + bob );
console.log("doug = " + doug);
};
inner_A();
};
mid_A();
},
outer_B = function () {
var mid_B = function () {
var doug = "Doug",
inner_B = function () {
console.log("INNER-B");
console.log("bob = " + bob );
console.log("doug = " + doug);
};
inner_B();
},
mid_C = function () {
var inner_C = function () {
console.log("INNER-C");
console.log("bob = " + bob );
console.log("doug = " + doug);
};
inner_C();
};
mid_B();
mid_C();
};
outer_A();
outer_B();
これはあなたに何をもたらしますか?
次のような出力が得られるはずです。
/*
INNER-A
bob = Bob
doug = undefined
INNER-B
bob = Bob
doug = Doug
INNER-C
bob = Bob
doug = undefined
*/
なぜあなたはそれで終わるのですか?
簡単に言えば、分岐する関数スコープがあるからです。
doug
の中で定義されていmid_B
ます。
の内部で作成された関数は、mid_B
潜在的に にアクセスできますdoug
。
の外部で作成された関数は にmid_B
アクセスできませんdoug
。
がinner_C
log を要求されるとdoug
、まずdoug
、自身の関数に存在するかどうかを確認します。
そうでない場合は、親の関数スコープ ( ) に存在するかどうかを確認しますmid_C
。そうでない場合は、親の関数スコープ ( )
に存在するかどうかを確認します。そうでない場合は、親の関数スコープ ( )
に存在するかどうかを確認します。
までずっと戻すと、親の関数スコープがありません...
...そうでない場合は、値を に設定します。outer_B
window
window
window
undefined
一方、inner_B
が見つからないのでdoug
、調べてmid_B
を見つけdoug
ます。
doug
これは「グローバル」にはなりません。
それはそれを作りますin-scope
。
「グローバル」は、、、、、、、およびすべてがアクセスouter_A
できる場合...mid_A
inner_A
outer_B
mid_B
inner_B
mid_C
inner_C
…そうでしょうbob
。
bob
グローバルです。
これは window オブジェクトにアタッチされているため (または で として定義されているため、var
グローバルglobal-scope
ですdelete
。
また、すべての子関数には に戻る関数スコープがあるためwindow
、すべての関数はのプロパティ/変数として定義されたものにアクセスできますwindow
(同じ名前のスコープチェーンのさらに上に変数があり、その時点で最初のものを選択する場合を除きます)ヒットします)。
これが意味することであり、この例では変数ではないglobal
理由です。doug
global