2

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

错误:未捕获的类型错误:对象 # 没有方法“第二”

我也试过不使用this关键字 like

Second("Bug") // Error: There is no method

而这是我正在玩的程序上的一种简化格式(为了显示一个简单的示例)。我正在努力找出原因。

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

4

2 回答 2

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

小提琴

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

于 2013-09-20T20:31:50.960 回答
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 约定。

于 2013-09-20T20:37:10.740 回答