我开始在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函数时(如我给出的例子),我不知道如何使用类属性。
这样做的最佳和最正确的方法是什么?
答案 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
对此非常方便:
答案 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}}