在JavaScript中使用“this”的明确方法

时间:2012-04-03 22:01:46

标签: javascript javascript-objects

我开始在JavaScript中定义类,关键字this我遇到了很多麻烦。

以下是我想要做的一个例子:

function MyMap() {

    this.map = new google.maps.Map(....);

    google.maps.event.addListener(this.map, 'idle', function() {
        this.mapIdle();    // PROBLEM: "this" undefined
    });

    this.mapIdle = function() {
        google.maps.event.addListener(marker, 'click', function() {
            $("button").click(function() {
                $.ajax({
                    success: function() {
                        this.map.clearInfoWindows(); // PROBLEM: "this" undefined
                    }
                });
            });
        });
    }
}

正如您在评论中看到的那样,this在这里不起作用,因为它在闭包中使用

我已开始使用workarounds,如:

var that = this;
google.maps.event.addListener(this.map, 'idle', function() {
    that.mapIdle();
});

或者甚至在你的回调函数周围必须define a callback function(严重!!)。

极端丑陋,无处不在。当我得到很多嵌套的lambda函数时(如我给出的例子),我不知道如何使用类属性。

这样做的最佳和最正确的方法是什么?

4 个答案:

答案 0 :(得分:3)

最简单的方法是定义一个self变量(或that,如果您不介意非语义变量名称),如上所述:

function MyMap() {
   var self = this;

   // in nested functions use self for the current instance of MyMap
}

注意您必须再次为添加到原型的方法(如果它们使用嵌套函数)执行此操作:

MyMap.prototype.myMethod = function() {
   var self = this;
   // use self in nested functions
};

您还应该阅读.bind() method,注意它不适用于IE< = 8。

关于定义回调回调的问题是解决一个不同的问题,即设置一个合适的闭包结构,允许嵌套在循环中的函数可以访问相应的循环计数器值(s )。这与this问题无关。 (并且在需要时可以很容易地与self技术结合使用。)

答案 1 :(得分:1)

如果您正在使用jQuery,$.proxy对此非常方便:

http://api.jquery.com/jQuery.proxy/

答案 2 :(得分:1)

您可以将对象和函数分配给局部变量,然后将它们包含在回调函数的闭包中:

function MyMap() {

  var map = new google.maps.Map(....);

  var mapIdle = function() {
    google.maps.event.addListener(marker, 'click', function() {
      $("button").click(function() {
        $.ajax({
          success: function() {
            map.clearInfoWindows();
          }
        });
      });
    });
  };

  this.map = map;
  this.mapIdle = mapIdle; // Is this needed?

  google.maps.event.addListener(this.map, 'idle', function() {
    mapIdle();
  });

}

答案 3 :(得分:1)

在JavaScript中,每个函数调用都会重新分配this

这只是你必须要注意的JavaScript。一开始可能会让人感到困惑,但是一旦你知道了一些简单的规则,它实际上非常简单。

如果是myObj.doSomething()之类的方法调用,那么this将自动设置为myObj内的doSomething()

如果您想在进行函数调用时明确控制this的值,可以使用doSomething.apply()doSomething.call()来控制this内设置的内容this功能。这就是事件处理程序回调的作用。他们明确地将this设置为指向创建事件的对象(非常有用的东西)。您可以在MDN上详细了解.apply().call()

如果你只是调用常规函数,那么window将被设置为全局对象,在浏览器中它是this对象。

所有回调函数的值都为this,因为每个函数调用都会更改this。由于您的事件处理程序是回调而成功处理程序是Ajax函数中的回调,因此您应该期望this的值不会从周围的代码中保留。有使用代理或绑定函数的解决方法,但通常在闭包中捕获var self = this;的先前值同样容易,只需使用类似this的内容访问它。

在您的情况下,当您想要从事件处理程序外部访问this指针时,正确的做法是将其保存到您将在事件处理程序中访问的本地变量,甚至是事件处理程序中的Ajax调用。没有更清洁的方法来做到这一点。这样您就可以访问来自事件的this指针或Ajax调用以及来自调用对象的 var self = this; self.mapIdle = function() { google.maps.event.addListener(marker, 'click', function() { $("button").click(function() { $.ajax({ success: function() { self.map.clearInfoWindows(); // PROBLEM: "this" undefined } }); }); }); } } 指针,如下所示:

{{1}}