【问题标题】:jQuery use an object's method as an event handlerjQuery 使用对象的方法作为事件处理程序
【发布时间】:2013-06-26 17:08:24
【问题描述】:

我有一个对象。它初始化一个按钮来提醒“你好!”当它被点击时。为什么这行不通?

jsfiddle:http://jsfiddle.net/kUT52/1/

HTML

<button>Test</button>

JS

var MyObject = {
  testValue: "Hello!",

  testFunction: function() {
    alert(this.testValue);
  },

  init: function(button) {
    button.click(this.testFunction());
  }
}

$(document).ready(function(){
  var buttonInstance = new MyObject();
  var button = $('button');
  buttonInstance.init(button);
});

【问题讨论】:

  • 你的代码没有意义!你不能像这样初始化一个新的对象字面量。如果您想使用new 并将其视为“构造函数”,则必须将MyObject 设为函数。否则,MyObject 是一个对象文字,您可以静态访问它 - MyObject.testValue
  • 大吃一惊@Ian。这让 js 对象更有意义,谢谢。

标签: javascript jquery oop event-handling jquery-events


【解决方案1】:

这是一个对象字面量,你通常会这样使用它:

var MyObject = {
    testValue: "Hello!",

    testFunction: function() {
        alert(MyObject.testValue);
    },

    init: function(button) {
        button.on('click', this.testFunction);
    }
}

var button = $('button');
MyObject.init(button);

FIDDLE

或传递对象:

var MyObject = {
    testValue: "Hello!",

    testFunction: function(e) {
        alert(e.data.obj.testValue);
    },

    init: function(button) {
        button.on('click', {obj: this}, this.testFunction);
    }
}

var button = $('button');
MyObject.init(button);

FIDDLE

【讨论】:

  • 好吧,它让警报工作了,但仍然警报“未定义”:P
  • @DonnyP - 没注意到!这是因为在 testFunction 的范围内,this 在以这种方式调用时将是按钮,而不是对象。您要么必须直接引用该对象,要么将this 作为参数传递。
【解决方案2】:

每当您将() 放在函数引用后面时,您就是在执行该函数。您必须将函数引用传递给.click,而不是函数返回的内容(除非函数返回您想用作事件处理程序的函数)。

例子:

button.click(this.testFunction);

但是现在你有另一个问题:在函数内部,this 将引用 DOM 元素而不是对象,因此访问 this.testValue 将返回 undefined

您可以使用 jQuery 的 $.proxy 函数来解决这个问题:

button.click($.proxy(this.testFunction, this));

现在this 将引用该对象,您可以通过event.target 获取对点击元素的引用。

【讨论】:

    【解决方案3】:

    有两个原因:

    • 您在绑定事件时使用的是testFunction() 而不是testFunction,因此您将调用函数并绑定(未定义的)返回值。

    • 当你把方法当成函数使用时,它不再附加到对象上,所以调用回调时上下文不会是对象,而是全局的window对象。

    使用proxy 方法创建一个函数,以正确的上下文调用该方法:

    button.click($.proxy(this.testFunction, this));
    

    【讨论】:

    • 感谢 Guffa,是否可以使用 .bind(this) 代替 $.proxy()?
    • @DonnyP 是的,他们完成了同样的事情
    • @DonnyP:是的,但这并不适用于所有浏览器。这就是proxy 存在的原因。
    • 语法是button.click(this.testFunction.bind(this)) 吗?
    • @Guffa 对我来说有趣的是 jQuery 甚至不检查Function.prototype.bind,他们总是使用他们自定义的方式
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-06
    • 1970-01-01
    • 2015-09-15
    • 1970-01-01
    • 2013-05-08
    相关资源
    最近更新 更多