使用 setTimeout 的变量范围

HMR*_*HMR 1 javascript scope settimeout

我很高兴它可以工作,但仍然对以下代码中“me”变量的范围有些困惑。现在使用它一段时间,但无法弄清楚它为什么起作用。

var timer=function(){
    this.timerMember=1;
    this.timerID=0;
    this.startTimer=function(){
        var me=this;
        this.timerID=setTimeout(function(){
            //shares scope with this.startTimer
            //timerMember is 2 here
            console.log(me.timerMember);
            // this is window
            console.log(this);
            // me doesn't exist in window
            console.log(this.me);
        },0);
//  this code gets executed before anonymous
//  timer function
//        clearTimeout(this.timerID);
        this.timerMember++;
    }
}
var t=new timer();
t.startTimer();
Run Code Online (Sandbox Code Playgroud)

传递给 setTimeout 的匿名函数似乎与 timer.startTimer 共享范围,但当匿名函数执行时 startTimer 显然已完成(me.timerMemer=2),因此当 startTimer 完成时,me 变量应该超出范围。幸运的是,JavaScript 会一直保留它,直到执行匿名函数(适用于所有浏览器),但我想知道这是否是正确的方法。这种行为是有意为之还是只是一个幸运的意外?

Guf*_*ffa 5

这是设计使然。这叫做闭包。

当一个函数在另一个函数中定义时,外层函数中的局部变量被放入一个闭包中,这样即使在外层函数结束后它们仍然存在。内部函数保留闭包,以便稍后访问变量。