setTimeout和这个 - 最简单的解决方案?

时间:2013-06-17 10:36:30

标签: javascript

众所周知,setTimeoutthis无法正常运行,因为它在全局范围内运行(this将为window

但我做了一个简单的test

用函数包装它:

var o={}
o.a=1;
o.m=function (){alert(this.a);}


setTimeout( 
  function (){
               o.m()  ;
             }

    ,100);

它确实警告1

我在这里遗漏了什么吗?为什么没有一个答案表明这个解决方案?它表现不同吗?

P.S。 :对于那些在这里遇到的人来说,它是一个失败的演示:

var o={}
o.a=1;
o.m=function (){alert(this.a);}


setTimeout( o.m   ,100); //undefined

3 个答案:

答案 0 :(得分:3)

执行此操作的正确方法是bind()匿名函数的范围。

var o = {};
o.a = 1;

setTimeout(function (){
    alert(this.a);
}.bind(o), 1000);

虽然您的答案会产生相同的结果,但它不会从匿名函数中访问o的范围。它只是调用全局对象o的函数。

您对this.a的引用属于o范围。

答案 1 :(得分:1)

您缺少闭包。您的回调函数可以访问o,即使它未被全局声明,只要回调是在 可以访问o的范围内定义的。

JS不能GC o,因为回调函数仍然引用它,因此你的代码段工作

示例:

(function()
{
    var scope = {};//an empty object
    setTimeout(function()
    {
        console.log(scope);
        console.log(typeof scope);
    },1000);
}());
console.log(scope);

在这里,您会看到undefined被记录,并且(大约)一秒钟之后,您会看到{}后面跟object出现。
鉴于:

var foo = {bar: 'foobar',
           callback: function()
           {
               console.log(this);
           }
};
setTimeout(foo.callback, 1000);
console.log(foo.callback());

首先记录由foo引用的对象,但是稍后,相同的函数对象将记录全局对象,因为(正如您所说),在全局上下文中调用函数引用。避免这种情况的唯一方法是使用bind,或者创建另一个闭包(但这会使我们太过分了。)

我已经详细介绍了JS的ad-hoc上下文绑定和引用解析herehereherehere等等等等< / p>

答案 2 :(得分:0)

“this”在不同的范围内定义不同,而您只在全局定义“o”。