为啥这个闭包不能访问 'this' 关键字? - jQuery

Posted

技术标签:

【中文标题】为啥这个闭包不能访问 \'this\' 关键字? - jQuery【英文标题】:Why doesn't this closure have access to the 'this' keyword? - jQuery为什么这个闭包不能访问 'this' 关键字? - jQuery 【发布时间】:2011-03-20 09:17:52 【问题描述】:

我是闭包(以及一般的 Javscript)的初学者,对于这段代码中发生的事情,我找不到令人满意的解释:

function myObject()
    this.myHello = "hello";
    this.myMethod = do_stuff;


function do_stuff()
    var myThis = this;
    $.get('http://example.com', function()
        alert(this.myHello);
        alert(myThis.myHello);
    );


var obj = new myObject;
obj.myMethod();

它会提示“未定义”,然后是“你好”。显然这不应该是特定于 jQuery 的,但这是我能想到的最简单的原始代码形式。 do_stuff() 中的闭包可以访问该范围内的变量,但显然这条规则不适用于 this 关键字。

问题:

当闭包在do_stuff()(在本例中为$.get())的范围之外传递时,this 会发生什么情况? myThis 是否包含 this 的副本或对其的引用?在闭包中使用this 通常不是一个好主意吗?

非常感谢任何回应。

【问题讨论】:

【参考方案1】:

当闭包在 do_stuff() 范围之外传递时会发生什么情况(在本例中为 $.get())?

每个函数都有自己的执行上下文,this 关键字检索当前上下文的值。

doStuff 标识符和 obj.myMethod 属性引用同一个函数对象,但由于您将其作为对象 (obj.myMethod();) 的属性调用,因此该函数内部的 this 值将引用到obj

当 Ajax 请求成功时,jQuery 将调用第二个函数(启动一个新的执行上下文),并将使用包含用于请求的设置的对象作为该回调的 this 值。

myThis 是否包含此内容的副本或对其的引用?

myThis 标识符将包含一个对象的引用,该对象也被外部作用域上的 this 值引用。

在闭包中使用它通常不是一个好主意吗?

如果您了解 this 值是如何隐式处理的,我看不出有什么问题...

由于您使用的是 jQuery,您可能需要检查 jQuery.proxy 方法,它是一种实用方法,可用于保存函数的上下文,例如:

function myObject()
    this.myHello = "hello";
    this.myMethod = do_stuff;


function do_stuff()
    $.get('http://example.com', jQuery.proxy(function()
        alert(this.myHello);
    , this)); // we are binding the outer this value as the this value inside


var obj = new myObject;
obj.myMethod();

另见:

‘this’ object can’t be accessed in private javascript functions without a hack?

【讨论】:

我本来想跟进,但你最新的编辑回答了这个问题。谢谢!【参考方案2】:
$.get('http://example.com', function()
    alert(this.myHello);  // this is scoped to the function
    alert(myThis.myHello);  // myThis is 'closed-in'; defined outside
);

注意匿名函数。这个范围内的 this 是函数的范围。 myThis 是外部作用域的 this,其中定义了 myHello。在 firebug 中查看。

'this' always 指的是当前的执行范围,我相信。如果您想获取当前范围并保留它,请执行您所做的操作,即将其分配给另一个变量。

【讨论】:

【参考方案3】:
$.get('http://example.com', function()
   // inside jQuery ajax functions - this == the options used for the ajax call
);

当闭包在 do_stuff() 范围之外传递时会发生什么(在本例中为 $.get())?

什么都没有发生,这仍然是 对于那个闭包,从闭包调用的函数的执行上下文不会自动继承 this

myThis 是否包含此内容的副本或对其的引用?

所有非标量赋值都是 JavaScript 中的引用。所以它是对this 的引用,如果您更改其中任何一个的属性,它们都会更改。

在闭包中使用它通常不是一个好主意吗?

在闭包中使用this 通常是个好主意,但是如果您要在内部使用需要访问相同this 的闭包,那么最好按照您所做的操作:@987654326 @ 然后使用someName访问

【讨论】:

以上是关于为啥这个闭包不能访问 'this' 关键字? - jQuery的主要内容,如果未能解决你的问题,请参考以下文章

Javascript:为啥访问闭包变量可能很慢

nodejs异步回调函数中this问题,求助

为啥我不能在箭头函数中访问“this”? [复制]

为啥不对对象属性使用闭包?

为啥我不能在 firebase 'then' 回调中访问 vuejs 'this'? [复制]

关于闭包