Javascript OOP : binding method to event handler

标签 javascript oop this

<分区>

我是 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????
  });
}

有效!?!?!

我的问题是:

  1. 为什么会这样?我知道this可能会有问题,但为什么将它分配给一个变量会改变它呢?
  2. 我做错了吗?有没有更好的方法以更优雅的方式实现这样的目标?

最佳答案

您发现了 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元素。

使用局部变量,如上面示例中的 game,意味着您创建的函数(“闭包”)将围绕该变量“关闭”,捕获范围内任何变量的值在定义函数的地方。任何变量 except this。因此,您的解决方法是处理此问题的一种非常常见的方法。

另一种常见的处理方法是使用像 Underscore.js 这样的库,它有一个名为 bind 的函数,它执行一些高阶函数魔法来确保 this 总是指向你想要的。

$('board').bind('click', _.bind(function(e) {
  this.handleClick(e);
}, this));

因此,Underscore.js 是我最喜欢的 Javascript 库之一(仅次于 jQuery),我几乎只将它用于绑定(bind)函数。

关于Javascript OOP : binding method to event handler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17311002/

相关文章:

jQuery $(this) 关键字

java - Pair 类 getPair 方法

javascript - 创建实时投票/结果页面

php - 寻找 getElementById 和 innerHTML 的 PHP 等价物

c - 如何用 C 语言编写面向对象的代码?

php - 不使用 setter 和 getter 真的错了吗?

jQuery $(this) 与 $.post() 的问题

javascript - 获取选择框以在不同的选择框中显示所选值

javascript - 'callbacks' 只是一个命名约定吗?

python - 使用类方法作为默认参数