変数は、クロージャーに対して「グローバル」にすることはできません。
それはグローバルかそうでないかのどちらかです。
そうでない場合は、関数スコープ内にあります。
それが関数のスコープ内にある場合、その関数の外にいるときにそれを取得する唯一の方法は、関数から返すプロパティにするか、オブジェクト/配列に追加することです。関数に渡されるか、その変数を返す関数の 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_Clog を要求されるとdoug、まずdoug、自身の関数に存在するかどうかを確認します。
そうでない場合は、親の関数スコープ ( ) に存在するかどうかを確認しますmid_C。そうでない場合は、親の関数スコープ ( )
に存在するかどうかを確認します。そうでない場合は、親の関数スコープ ( )
に存在するかどうかを確認します。
までずっと戻すと、親の関数スコープがありません...
...そうでない場合は、値を に設定します。outer_B
window
window
windowundefined
一方、inner_Bが見つからないのでdoug、調べてmid_Bを見つけdougます。
dougこれは「グローバル」にはなりません。
それはそれを作りますin-scope。
「グローバル」は、、、、、、、およびすべてがアクセスouter_Aできる場合...mid_Ainner_Aouter_Bmid_Binner_Bmid_Cinner_C
…そうでしょうbob。
bobグローバルです。
これは window オブジェクトにアタッチされているため (または で として定義されているため、varグローバルglobal-scopeですdelete。
また、すべての子関数には に戻る関数スコープがあるためwindow、すべての関数はのプロパティ/変数として定義されたものにアクセスできますwindow(同じ名前のスコープチェーンのさらに上に変数があり、その時点で最初のものを選択する場合を除きます)ヒットします)。
これが意味することであり、この例では変数ではないglobal理由です。dougglobal