node.js参数隐藏

时间:2012-09-07 20:53:26

标签: 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?

1 个答案:

答案 0 :(得分:2)

outID在顶级范围内声明(即使用var关键字),并且从不在任何其他(函数)范围内重新声明。这意味着,当它被分配到任何地方时,它会写入同一个变量,并且当它被引用时,它会从同一个变量中读取。

要保持内部函数中的outID=3行不会更改最后打印的值,您需要将其更改为var outID=3

编辑:

发布的代码具有以下范围:

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

由于希望更清楚,函数作用域继承自定义的作用域,而不是 的作用域。当然,您可能会将范围与this的值混为一谈,这是另一个故事......