关于setTimeout函数中的闭包问题

来源:互联网 发布:数据采集系统应用领域 编辑:程序博客网 时间:2024/04/25 09:57

今天看到这么一道题:

function Dog(msg){    this.msg=msg;    this.eat=function(){        alert(this.msg);        }    this.work=function(){        setTimeout(this.eat,2000);      }   }var o=new Dog("bones");o.work(); //返回结果是undefined

下面我来解释一下结果为什么是undefined,为什么没有输出预期的“bones”。
这是因为在执行完o.work()这行代码时,this对象已经被释放了,不再指向o了;然后经过2秒后,再执行this.eat函数时,此时的this指向全局变量window,而在全局空间并没有eat函数,因而返回undefined。

那么怎么改代码似的结果返回”bones”呢?这样做:

function Dog(msg){    this.msg=msg;    this.eat=function(){        alert(this.msg);        }    this.work=function(){        var that=this;        setTimeout(function(){            that.eat();        },2000);        }   }var o=new Dog("bones");o.work(); //返回结果是"bones"

这里用到了闭包的知识。
分析:
在执行到o.work时,用变量that保留了此时this的引用(即o),然后在setTimeout中,写了一个匿名函数,在匿名函数内部引用了that,而that引用了o,造成o不会被释放掉。这是闭包的知识。
然后2秒后,在执行setTimeout内的匿名函数时,此时执行that.eat(),that可以通过作用域链找到最近一次对它定义的值,即上面所定义的对o的引用,故能取到o.msg的值,执行o.eat()返回”bones“。

0 0
原创粉丝点击