2011-11-14 31 views
1

考虑下面的代码:的JavaScript - 引用“这”在内部功能

MyClass.prototype.my_func = function() { 
    this.x = 10; 
    $.ajax({ 
     // ... 
     success: function (data) { 
      alert(this.x); 
     } 
    }); 
} 

它不工作,因为显然this没有被绑定到闭包的执行上下文。我已经能够通过引入另一个变量去解决它周围:

var _this = this; 

而且这部作品匿名函数内部。但对我来说看起来很难看。有一些很好的方法来处理这个问题吗?

+9

我认为你提出的解决方案 - 'var _this = this;' - 是标准的解决方法。 – LukeH

+0

标准解决方法使用'var that'代替:P – hugomg

+0

@LukeH我会尽可能地去**不**甚至称它为*解决方法* – ZenMaster

回答

2

这可能看起来像您的丑陋解决方案,并且有一些步骤(例如using bind() method来更改上下文),但这是我所知道的最佳解决方案。

或者你可以把它改成:

var self = this; 

或给它更有意义的名称,但它是(在这种情况下)不改变的背景下更好,因为你可能需要一些日子。

1

可以使Function.prototype.bind用法为:

MyClass.prototype.my_func = function() { 
    this.x = 10; 
    $.ajax({ 
     // ... 
     success: function (data) { 
      alert(this.x); 
     }.bind(this); 
    }); 
} 

现在父上下文变量也势必匿名函数。

+0

似乎并不适合我在FF 3.6和IE8 –

+0

@安迪:好吧,那很可能。 '.bind()'从ES5规格来说是相当新颖的,所以旧式浏览器可能不支持它。 – jAndy

+0

@Andy:在我的回答中,我给出了有关'bind()'的MDN文章的链接以及如何在旧版浏览器上实现它的链接,以便您可以在那里看到它。但我仍然认为这不是我们要走的路,正如我在答复中提到的那样。 – Tadeck

0

this语法通常是指对象,而不是一个函数。在你的情况下,this是指MyClass

如果您在对象中使用变量,您可能忘记在MyClass中定义x

如果你只在函数中使用变量,我会使用var语法来定义我的变量。函数中定义的变量在函数结束时被销毁。

MyClass.prototype.my_func = function() { 
    var x = 10; 

    $.ajax({ 
     // ... 
     success: function (data) { 
      alert(x); 
     } 
    }); 
} 
0

闭包将有权访问其父上下文中定义的所有对象。因此,如果我们有:

function() { 
    var x = 10; 
} 

然后,这是有效的:

function() { 
    var x = 10; 

    (function() { 
    alert(2*x); // 20 
    }()) 
} 

因此,当你定义var _this = this你只是定义在父母的背景下,新的变量,它是可用的闭包内。有关此“模式”的更多信息,请参阅question #4371333