gpt4 book ai didi

JavaScript 闭包和 this 对象

转载 作者:搜寻专家 更新时间:2023-11-01 04:10:45 27 4
gpt4 key购买 nike

我以为我对 JavaScript 中的 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在第一种情况下指向了window对象,但在其他情况下,它不应该。我尝试在返回之前在 makeClosure 函数中记录 this,它确实记录了对象本身,而不是 window 对象。但是当使用实际的闭包时,this 又回到指向 window 对象。为什么?

我唯一能想到的是,通过将 anyFunc 函数作为参数传递,我实际上传递了 window.anyFunc。所以我尝试了这个快速修复:

function makeClosure(func)
{
var theFunc = func;
return function(par)
{
theFunc(par);
}
}

有了预期的结果,this 现在指向对象,但再次:为什么?我有一些想法(theFunc 是对局部范围 [this > private: theFunc] 中函数的引用?),但我确定这里有人在 JS 方面有更多的专业知识,所以我希望能从他们那里得到更多的解释或指向值得阅读的文章的链接……

谢谢

更新

Here's a fiddle ,可能是我遗漏了一些东西,但是这里记录了各种各样的事情;)

编辑/更新 2

The case that confuses me在这里。

最终编辑

好的,这是一个相当困惑的帖子。所以澄清一下:我所期待的是与此类似的行为:

function makeClosure()
{
function fromThisFunc()
{
console.log(this);
}
return fromThisFunc;
}

var windowContext = makeClosure();
windowContext();
var objectContext = {cls:makeClosure()};
objectContext.cls();

引起我注意的是,函数anyFunc 没有在正确的范围内声明,因此,this 指向了window 对象。我通过阅读 ancient scroll 发现了这一点我在网上找到了某个地方。

But something a little more complicated has happened because the function object now referred to by globalVar was created with a [[scope]] property referring to a scope chain containing the Activation/Variable object belonging to the execution context in which it was created (and the global object). Now the Activation/Variable object cannot be garbage collected either as the execution of the function object referred to by globalVar will need to add the whole scope chain from its [[scope]] property to the scope of the execution context created for each call to it.

所以我需要做的是简化而不是复杂化:

function fromThisFunc()
{
console.log(this);
}

function makeClosure(funcRef)
{
//some code here
return funcRef;
}

这应该行得通,对吧?

PS:我将排除 Alnitak 的回答,但特别感谢 Felix Kling 的所有耐心和信息。

最佳答案

只要你打电话:

return func(par);

你正在创建一个新的范围(有它自己的 this),在这种情况下,因为你没有指定一个对象,this === window 通常或者undefined 在严格模式下。被调用函数不会继承调用范围内的任何this

this 设置值的方法有:

myobj.func(par);  // this === myobj

func.call(myobj, ...)  // this === myobj

还有:

关于JavaScript 闭包和 this 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10512087/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com