我原以为自己对JavaScript中的
我已经深深地爱上了JavaScript,特别是纯JS,而不是jQuery、prototype.js、dojo等库。因此,我开始使用闭包。但在某些情况下,
在所有三种情况下,
这个修复方法有效,我在这里放置它是为了避免人们回答这个问题,而不解释我需要知道的原因:为什么它在这里表现出这种行为?
确保调用者有效地是闭包所属的对象。我不明白的是这个: 当然,在第一种情况下,
我唯一能想到的是,通过将
我注意到的是,函数
this
对象有一个合理的理解。在处理对象、回调函数、事件和处理程序时,自古以来我都没有遇到过问题。然而,现在一切都改变了。我已经深深地爱上了JavaScript,特别是纯JS,而不是jQuery、prototype.js、dojo等库。因此,我开始使用闭包。但在某些情况下,
this
却让我措手不及。例如,看看这段代码:function anyFunc(par)
{
//console.log(par);
console.log(this);
}
function makeClosure(func)
{
return function(par)
{
return func(par);
}
}
var close = makeClosure(anyFunc);
close('Foo');
var objWithClosure = {cls:makeClosure(anyFunc),prop:'foobar'};
objWithClosure.cls(objWithClosure.prop);
var scndObj = {prop:'Foobar2'};
scndObj.cls = makeClosure;
scndObj.cls = scndObj.cls(anyFunc);
scndObj.cls(scndObj.prop);
在所有三种情况下,
this
都作为窗口对象记录。当然,这是一个容易解决的问题:function makeClosure(func)
{
return function(par)
{
return func.call(this,par);
}
}
这个修复方法有效,我在这里放置它是为了避免人们回答这个问题,而不解释我需要知道的原因:为什么它在这里表现出这种行为?
确保调用者有效地是闭包所属的对象。我不明白的是这个: 当然,在第一种情况下,
this
指向窗口对象,但在其他情况下,它不应该。我尝试在返回之前在makeClosure函数中记录this
,它确实记录了对象本身,而不是window
对象。但是当实际闭包被使用时,this
又会指向窗口对象。为什么?我唯一能想到的是,通过将
anyFunc
函数作为参数传递,我实际上是传递了window.anyFunc
。所以我尝试了这个快速修复:function makeClosure(func)
{
var theFunc = func;
return function(par)
{
theFunc(par);
}
}
有了预期的结果,this
现在指向对象,但是为什么呢?我有一些想法(theFunc
是本地作用域中函数的引用[this > private: theFunc
]?),但我相信这里有很多在JS方面更有专业知识的人,所以我希望能从他们那里得到更多解释或值得阅读的文章链接...
谢谢
更新
这里有一个fiddle, 可能我漏掉了一些东西,但这里记录了各种各样的东西;)
编辑/更新2
让我困惑的情况在这里。
最终编辑
好的,这篇文章变得有点混乱了。所以澄清一下:我期望的行为类似于这个:
function makeClosure()
{
function fromThisFunc()
{
console.log(this);
}
return fromThisFunc;
}
var windowContext = makeClosure();
windowContext();
var objectContext = {cls:makeClosure()};
objectContext.cls();
我注意到的是,函数
anyFunc
没有在正确的作用域内声明,因此this
指向了窗口对象。我通过阅读在网上找到的古代卷轴发现了这一点。
所以我需要做的是简化而不是复杂化事情:但是因为全局变量现在引用的函数对象具有[[scope]]属性,该属性引用包含执行上下文中的激活/变量对象(和全局对象)的作用域链。现在,激活/变量对象也无法进行垃圾回收,因为由globalVar引用的函数对象的执行将需要将整个作用域链从其[[scope]]属性添加到为每次调用它创建的执行上下文的作用域中。
function fromThisFunc()
{
console.log(this);
}
function makeClosure(funcRef)
{
//some code here
return funcRef;
}
这应该可以正常工作,对吧?
附注:我会接受Alnitak的答案,但特别感谢Felix Kling的耐心和信息。
this
对象会发生什么。 - Elias Van OotegemDOMWindow
,Object
,Object
:http://jsfiddle.net/GErkX/,而您的第二个“修复”给了我 3 个DOMWindow
:http://jsfiddle.net/tZXQF/。 - Felix Klingfunc(par)
,因此在函数内部,this
指向window
。这就是你期望的第一个情况。 - Felix Kling