2012-09-07 137 views
0

我在測試node.js中的回調機制以查看引發回調的上下文。在運行下面的代碼,我注意到一個奇怪的行爲,我不知道你能不能解釋一下: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] 

爲什麼是最後一個值3,而不是2?

+0

爲什麼當你將它設置爲3時,在你調用的構造函數中它的值應該是2 ? – JohnnyHK

+0

是的,我明白這是因爲我寫的。我只是不知道在運行timeOut時node.js如何知道這些值(符號?)? – qballer

回答

2

outID在頂級作用域中聲明(即使用關鍵字var),並且從不在任何其他(函數)作用域中重新聲明。這意味着,當它被分配到任何地方時,它將寫入同一個變量,並且在任何地方被引用時,它將從同一個變量讀取。

要使outID=3行保留在內部函數中,以更改上次打印的值,請將其更改爲var outID=3

編輯:

代碼張貼有以下範圍:

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

作爲有希望使更清晰,一個功能範圍從其所定義範圍,而不是範圍在繼承它是,被稱爲。當然,你可能會將範圍與this的值相混淆,這是另一個故事...

+0

所以setTimeout屬於哪個範圍? – qballer