2017-01-19 8 views
0

これがあまりにも素朴であれば申し訳ありませんが、別の質問に答えようとしている間にこれに固執しています。 :)下のコードでは、bar.xbar.yの両方に似ています/同じ機能体があります(関数が最初に宣言されている場所は?)。そしてfooのスコープはyに割り当てられても失われますが、それでもbar.y()と呼ぶと、なぜ閉じ込め内にglobal_varが入りませんか? xyの両方に300を出力できる方法はありますか?これらの2つの機能の範囲の違い

global_var = 2 
 
var foo = function(){ 
 
    console.log("y", global_var) 
 
} 
 
var bar = (function b(){ 
 
    var global_var = 300; 
 
    var x = function(){ 
 
    console.log("x",global_var); 
 
    }; 
 
    var y = foo; 
 
    return {x: x, y: y}; 
 
})(); 
 

 
bar.x(); //300 
 
bar.y(); //2 
 
setTimeout(bar.x); //300 
 
setTimeout(bar.y); //2

答えて

1

は問題でそれをしません関数が最初に宣言される場所

はい。関数のスコープは、宣言されている場所によってのみ決定されます。

、私はそれがスコープが変更されていないY

号に割り当てられている場合FOOの範囲が失われていることを推測します。

私がbar.y()を呼び出すと、なぜglobal_varがクロージャの中に入っていないのですか?

と宣言されているために関数の範囲が決まっているためです。

xとyの両方が300を出力できる方法はありますか?

スコープでつぶやくのではありません。

他の場所からデータを取得するには、関数を書き直す必要があります。オブジェクトのプロパティから

var global_object = {}; 
 
global_object.data = 1; 
 

 
global_object.foo = function() { 
 
    console.log("y", this.data); 
 
}; 
 

 
var bar = (function b() { 
 
    var local_object = {}; 
 
    local_object.data = 2; 
 
    local_object.x = function() { 
 
    console.log("x", this.data); 
 
    }; 
 
    local_object.y = global_object.foo; 
 
    return local_object; 
 
})(); 
 

 
bar.x(); // 2 
 
bar.y(); // 2 
 
setTimeout(bar.x.bind(bar)); // 2 
 
setTimeout(bar.y.bind(bar)); // 2

+0

「this」とレキシカルスコープの私のコンセプトが混ざっていると思います。 – sabithpocker

1

yfooの割り当てに関与何の閉鎖はありません。関数fooのスコープは、コードサンプルの先頭にある定義されている場所で決定され、その関数本体の内部にあるglobal_varは、常に1行目に(暗黙的に)定義された変数global_varを参照します。同じ名前の他の変数はありません。

foo~yを割り当てても、その機能の範囲には影響しません。割り当てが達成するのは、新しい変数からfooにアクセスできるようにすることだけです。

xとyの両方が300を出力できる方法はありますか?

ない機能がそのように定義されていますが、thisを使用する場合は、あなたが期待しているものと同様のものを持っている可能性があり:

global_var = 2 
 

 
var foo = function(){ 
 
    console.log("y", this.global_var) 
 
} 
 

 
var bar = (function b(){ 
 
    var global_var = 300; 
 

 
    var x = function(){ 
 
    console.log("x", this.global_var); 
 
    }; 
 

 
    var y = foo; 
 

 
    return {x: x, y: y, global_var: global_var}; 
 
})(); 
 

 
foo();      // 2 
 

 
bar.x();      // 300 
 
bar.y();      // 300 
 

 
setTimeout(bar.x);   // 2 
 
setTimeout(bar.y);   // 2 
 

 
setTimeout(bar.x.bind(bar)); // 300 
 
setTimeout(bar.y.bind(bar)); // 300

+0

私はちょうど私達が 'this'をバインドする方法と同様にレキシカルスコープを変更しようとしていました。今私はどこが間違っているのか理解しています。 – sabithpocker

関連する問題