Javascript函数对象,该关键字指向错误的对象
在javascript函数对象中使用javascript“this”关键字时,我遇到了一个问题。我希望能够创建一个对象来处理模式弹出窗口(jQueryUI对话框) 该对象称为CreateItemModal。我希望能够实例化并传递一些配置设置。配置设置之一。调用show方法时,将显示对话框,但cancel按钮不起作用,因为它引用的是DOM对象而不是CreateItemModal对象 我如何解决这个问题,或者是否有更好的方法将分离的行为放在分离的“类”或“对象”中。我尝试了几种方法,包括将“this”对象传递到事件中,但这并不是一个干净的解决方案 见以下(简化)代码:Javascript函数对象,该关键字指向错误的对象,javascript,jquery,this,Javascript,Jquery,This,在javascript函数对象中使用javascript“this”关键字时,我遇到了一个问题。我希望能够创建一个对象来处理模式弹出窗口(jQueryUI对话框) 该对象称为CreateItemModal。我希望能够实例化并传递一些配置设置。配置设置之一。调用show方法时,将显示对话框,但cancel按钮不起作用,因为它引用的是DOM对象而不是CreateItemModal对象 我如何解决这个问题,或者是否有更好的方法将分离的行为放在分离的“类”或“对象”中。我尝试了几种方法,包括将“this
function CreateItemModal(config) {
// initialize some variables including $wrapper
};
CreateItemModal.prototype.show = function() {
this.$wrapper.dialog({
buttons: {
// this crashes because this is not the current object here
Cancel: this.close
}
});
};
CreateItemModal.prototype.close = function() {
this.config.$wrapper.dialog('close');
};
试试这个:
CreateItemModal.prototype.show = function() {
var me = this;
this.$wrapper.dialog({
buttons: {
// this crashes because this is not the current object here
Cancel: me.close
}
});
};
它不起作用的原因,因为“this”指的是对话框,而不是那个类。尝试添加一个等于全局this的变量,例如
function CreateItemModal(config) {
// initialize some variables including $wrapper
};
CreateItemModal.prototype.show = function() {
var $this = this;
this.$wrapper.dialog({
buttons: {
// this crashes because this is not the current object here
Cancel: $this.close
}
});
对我来说,它在大多数情况下都有效您需要创建一个闭包来捕获
此
上下文,我倾向于使用匿名函数来完成此操作,如下所示:-
CreateItemModal.prototype.show = function() {
this.$wrapper.dialog({
buttons: {
// this crashes because this is not the current object here
Cancel: (function(self) {
return function() { self.close.apply(self, arguments ); }
})(this);
}
});
};
在JavaScript中遇到“this”问题的每个人都应该阅读并消化这篇博文:
你也可以在谷歌上搜索“道格拉斯·克罗克福德”,并观看他的一些(免费)视频;上面的代码没有任何变化。close函数仍然在button元素的上下文中执行,而不是在
CreateItemModal
实例中执行。正确,一分钟前刚刚对其进行了测试,这将无法正常工作。没错,因为me.close
作为函数存储在Cancel
中:其包含的对象me
丢失。所以当执行它时,这个
是窗口
。这是有效的,但是这是“最佳实践”吗?让javascript将其视为真正的“OO”对象似乎会带来很大的开销?这是因为您使用的是jQuery,而jQuery并不是用来帮助您编写这种javascript的。对于大多数其他框架,您只需编写Cancel:this.close.bind(this)
@Rody:这是唯一的做法。ECMAScript第5版介绍了函数原型方法bind
,它允许您执行如下操作:Cancel:this.close.bind(this)代码>。如果您必须在整个代码中多次执行此类操作,bind
prototype的实现在web上随处可见。@Andy E:谢谢您为我清除了它。将研究javascript的闭包行为,见过几次,但从未真正深入研究过。@Alsciende:只是为了澄清,提供bind
的框架并没有消除闭包的开销,因为在内部,它们将使用闭包来实现闭包。