我是JS的新手,我理解函数是声明“类似”结构的方法。 我正在尝试做这样的事情:
function Game() {
// Class stuff
this.handleClick = function(e) {
alert(e);
}
// Bind event to method previously defined
$('#board').bind('click', function(e) {
this.handleClick(e); // <--- THIS IS THE PROBLEMATIC LINE
});
}
现在,如果在“有问题的一行”我写道:
handleClick(e)
我得到Uncaught ReferenceError: handleClick is not defined
。
相反,如果我写:
this.handleClick(e);
我得到Uncaught TypeError: Object #<HTMLCanvasElement> has no method 'handleClick'
但是,如果我这样做:
function Game() {
// Class stuff
this.handleClick = function(e) {
alert(e);
}
var game = this; // <--- I ASSIGN this TO board
// Bind event to method previously defined
$('#board').bind('click', function(e) {
game.handleClick(e); // <--- THIS WORKS!! WHY????
});
}
它有效!?!?!
我的问题是:
this
可能有问题,但为什么将它分配给变量会改变它?答案 0 :(得分:4)
你在Javascript的闭包实现中找到了一个漏洞。 (如果您不知道闭包是什么,请不要担心。)
Javascript中的 this
引用了调用该函数的对象。因此,如果您的对象具有恰好被赋予函数值的属性,并且您调用该属性,则this
指针将引用该对象。它没有引用创建函数的任何this
,也没有引用函数本身。
var object = {};
object.myfunc = function() { console.log(this); } //<-- this will refer to object
object.myfunc();
在事件处理程序的情况下,处理程序函数(在纯Javascript中,忽略jQuery)被分配给DOM元素,因此它从该元素调用,因此this
指向DOM元素。 / p>
在上面的示例中使用局部变量(如game
)意味着您创建的函数(“闭包”)将“关闭”该变量,捕获该位置范围内任何变量的值功能已定义。除 this
之外的任何变量。因此,您的解决方法是处理此问题的一种非常常见的方法。
处理这个问题的另一种常见方法是使用像Underscore.js这样的库,它有一个名为bind
的函数,可以执行一些高阶函数魔法,以确保this
总是指向什么你想要的。
$('board').bind('click', _.bind(function(e) {
this.handleClick(e);
}, this));
出于这个原因,Underscore.js是我最喜欢的Javascript库之一(在jQuery之后),我几乎专门用于绑定函数。