0

コールバックが発生するコンテキストを確認するために、node.js でコールバック メカニズムをテストしていました。次のコードを実行しているときに、奇妙な動作に気付きました。説明していただけないでしょうか。

var outID =2;

var closure = function (){
    var that = {};
    that.id = 1;
    outID = 3; //if line is commented out outID will always be 2.
    that.inside  = function(cb){
        console.log("level 0");
        console.log("thatID:" +that.id);
        console.log("outID:" +outID);
        setTimeout(function(){
            console.log("level 1");
            console.log("thatID:" +that.id);
            console.log("outID:" +outID);
            setTimeout(function(){
                setTimeout(cb,0,that.id);
            },0);
        }, 0);
    };
    return that;
};
var level3  = function(id){
    console.log("level 100S");
    console.log("id " + id);
    console.log(outID); // --- Interesting value is 3.
};
var cl = new closure();
cl.inside(level3);

出力は次のとおりです。

node: no process found
level 0
thatID:1
outID:3
level 1
thatID:1
outID:3
level 100S
id 1
3
[Finished in 0.1s]

最後の値が 2 ではなく 3 なのはなぜですか?

4

1 に答える 1

2

outIDvar最上位スコープで(つまり、キーワードを使用して) 宣言され、他の (関数) スコープで再宣言されることはありません。これは、どこに割り当てられても同じ変数に書き込み、どこからでも参照されると同じ変数から読み取ることを意味します。

内部関数のoutID=3行が最後に出力された値を変更しないようにするには、それを に変更しvar outID=3ます。

編集:

投稿されたコードには、次のスコープがあります。

global 
    closure
         that.inside
             $anonymous1 (outer setTimeout argument)
                  $anonymous2 (inner setTimeout callback)
    level3

うまくいけばより明確になるように、関数スコープは、それが呼び出されたスコープではなく、定義されたスコープから継承します。もちろん、スコープを の値と混同している可能性がありますが、これは別の話です...this

于 2012-09-07T21:12:36.037 に答える