在事件处理程序中调用函数

时间:2013-09-20 20:29:48

标签: javascript javascript-events event-handling jquery

我在 Javascript 代码中编写了2个函数,如下所示

Manager = FormManager.extend({
    First: function () {
     var response = this.Second("Feature"); //I'm able to get the alert

     //I have added a click event handler
     $('#element').on('click', function(){
       var newResponse = this.Second("Bug"); //The alert is not poping
     });

    }

    Second: function (type) {
     alert(type);
     //Performs certain operation
    }
});
  

错误:未捕获TypeError:对象#没有方法'秒'

我也尝试过不使用像

这样的 this 关键字
Second("Bug") // Error: There is no method

虽然这是我正在玩的程序的简化格式(按顺序显示一个简单的例子)。我正在努力找出原因。

有人可以指引我走正确的道路吗?

2 个答案:

答案 0 :(得分:6)

您使用的是不正确的this。试试这种方式。处理程序内的this表示#element而不是函数本身的上下文。

 var self = this; //cache the context here
 $('#element').on('click', function(){
   var newResponse = self.Second("Bug"); //Access it with self
 });

此外,我认为您在First功能定义之后和Second功能之前缺少逗号。

<强> Fiddle

您给出的回调的原因是从元素的上下文中调用的,因此您的this上下文会发生变化。 this上下文是指调用回调的上下文。但是还有其他方法可以解决这个问题,例如使用$.proxy同时使用ecquScript5 Function.prototype.bind等将回调绑定到jquery等。但理想情况下,您不希望这样做,因为大多数情况下您需要处理程序内部元素的上下文。

答案 1 :(得分:2)

每次在函数中使用this上下文变量时,都必须考虑其值是什么。

具体而言,该值将是调用者指定的任何值,无论是使用myObj.mymethod(...)还是mymethod.call(myObj, ...)还是mymethod.apply(myObj, [ ... ])

当调用匿名函数$('#element').on('click', ...)时,jQuery会将上下文设置为HTML DOM元素 - 它不再引用您的对象。

最简单的解决方法是在回调之外获取this的副本,然后在闭包内引用该副本,即:

var that = this;
$('#element').on('click', function() {
     // use that instead of this, here
     console.log(this);    // #element
     console.log(that);    // your object
});

另一种方法是使用Function.prototype.bind

$('#element').on('click', (function() {
     console.log(this);    // your object
}).bind(this));

或者使用jQuery,您可以使用$.proxy获得相同的效果,因为.bind是ES5函数。

我实际上更喜欢var that = this方法,因为它不会破坏this引用与事件关联的元素的jQuery约定。