2012-09-07 96 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