众所周知,setTimeout
与this
无法正常运行,因为它在全局范围内运行(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
答案 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
,或者创建另一个闭包(但这会使我们太过分了。)
答案 2 :(得分:0)
“this”在不同的范围内定义不同,而您只在全局定义“o”。