JavaScript的关闭和这个对象(JavaScript closure and the this

2019-06-24 06:28发布

我以为我有一个合理的理解this对象在JavaScript中。 当对象,回调和事件和处理程序处理,我还没自古以来有相关的问题。 然而现在,一切都变了。

我已经爱上神魂颠倒地爱上了JavaScript的。 纯JS,那就是没有了jQuery,prototype.js中,道场......所以很自然的,我已经采取了使用闭包。 在某些情况下,虽然, 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点在第一种情况下的窗口对象,但在其他情况下,它不应该。 我试图登录this只是在返回之前在makeClosure功能,它没有记录的对象本身,而不是window对象。 但是实际使用的时候关闭, this是回指向window对象。 为什么?

我能想到的唯一的事情就是,通过将anyFunc函数作为参数,实际上,我路过window.anyFunc 。 所以,我想这个快速修复:

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

随着预期的结果, this现在指向的对象,但再次:为什么呢? 我有几个想法的( theFunc是在局部范围内[给函数的引用this > private: theFunc ]?),但我敢肯定还有人在这里有很多诀窍,当谈到JS,所以我希望能得到一些更多的解释或链接到值得他们阅读的文章...

谢谢

更新

这里有一个小提琴 ,可能是我离开的东西了,但在这里,这会将所有的事情;)

编辑/更新2

这混淆了我的情况是在这里。

最后编辑

OK,这是得到一个相当混乱的帖子。 因此,为了澄清:我期待类似于这样的行为:

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

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

什么抓住了我,是功能anyFunc不正确的范围内声明的,因此, this指出了窗口对象。 我发现了这一点,通过读取一个古老的卷轴我发现某处在网络上。

但一些更复杂的发生,因为现在通过globalVar称为功能对象是使用所创建的[[范围]]属性指含有属于在其创建执行上下文激活/变量目的的范围链(和全局对象)。 现在激活/可变对象不能被垃圾收集或者作为功能对象的执行通过globalVar称为将需要从它的[[范围]]属性添加整个作用域链到执行上下文的每次调用创建的范围它。

因此,我需要做的,就是简化而不是复杂的事情:

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

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

这应该工作,对不对?

PS:我会除外参宿一的答案,但特别感谢费利克斯·克林所有的耐心和信息。

Answer 1:

只要您拨打:

return func(par);

您正在创建一个新的范围(有自己的this ),在这种情况下,因为你没有指定的对象, this === window通常或不确定的严格模式。 被调用的函数继承无论this是在呼叫范围内。

方式设置值, 是:

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

要么

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

也有:

  • 应用
  • 捆绑
  • 箭头功能 ,其中被设置为相同的值作为外执行上下文(也参见MDN:箭头功能


Answer 2:

this仅取决于你是否调用该函数的方法或作为一个功能。

如果你把它作为一种方法, this将是该方法属于对象:

obj.myFunction();

如果你把它作为一个功能, this将是window对象:

myFunction();

请注意,即使你是属于对象的方法,你还必须调用使用该方法的语法对象的其它方法,否则会被称为功能:

this.myOtherFunction();

如果你在一个变量放在一个方法引用,你会从对象脱离它,它会被称为函数:

var f = obj.myFunction;
f();

callapply方法被用来调用一个函数为方法,即使它不是在对象的方法(或,如果它是一种在不同的对象):

myFunction.call(obj);


文章来源: JavaScript closure and the this object