我在JavaScript代码中编写了两个函数,如下所示
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
关键字,例如:
Second("Bug") // Error: There is no method
而这是我正在使用的程序上的简化格式(为了显示一个简单的示例)。 我正在努力找出原因。
有人可以指引我走正确的道路吗?
您使用了不正确的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
上下文会发生变化。 this
上下文是指从中调用回调的上下文。但是还有其他方法可以解决这个问题,比如使用 $.proxy 同时使用 jquery 绑定回调,使用 EcmaScript5 Function.prototype.bind 等。但理想情况下,您不想这样做,因为在大多数情况下,您需要处理程序中元素的上下文。
每次在函数中使用 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
方法,因为它不会破坏 jQuery 约定,即this
引用与事件关联的元素。