我有一个关于在对象中维护this
范围的一般性问题。这是一段简化的代码片段。记下var that = this
行以及我调用that.showMenu()
的事件处理程序内部。
var MyObj = {
init : function(target){
this.$Target = $(target);
this.$Menu = $(target).find('.menu');
this.eventBindings();
},
eventBindings : function(){
var that = this;
this.$Target.on('click', '.anchor', function(e){
e.preventDefault();
that.showMenu();
//some other code
});
},
showMenu : function(){
this.$Menu.show();
}
};
MyObj.init('.myTarget')
代码应该有点自我解释。通常我会尝试在eventBindings()
之外创建可重用的方法。我不断遇到的问题是通过this
将MyObj
引用到事件处理程序中,以便我可以调用this.showMenu()
。
为了克服这个障碍,我总是将this
分配给一个名为that
的变量,所以当我进一步向下范围时,我有一个参考。但我觉得这不是最好的方法......有人可以提出更好的选择吗?
答案 0 :(得分:1)
你在做什么是最好的方法。在Javascript中this
是动态范围的(绑定依赖于堆栈,即位于调用函数的位置),所有其他变量 - 都是静态范围的(绑定取决于代码中变量的静态位置)。
由于Javascript以特殊方式处理this
,因此也不要以特殊的方式对待它。
您可以在函数中封装您现在正在执行的操作 - 许多库提供了这样的工具,通常称为“绑定”。但这不会改变真正发生的事情,只会隐藏它(并在执行此操作时耗尽一些资源)。这样的功能看起来有点像:
function whatever (functionToProcess, thisToFreeze) {
return function() {
functionToProcess.apply(thisToFreeze, arguments); // apply is built in
}
}
答案 1 :(得分:0)
继@ Pointy的评论,使用Function.prototype.bind
:
onClick: function(e){
e.preventDefault();
this.showMenu();
//some other code
},
eventBindings : function(){
this.$Target.on('click', '.anchor', this.onClick.bind(this));
},
答案 2 :(得分:0)
您可以将其作为事件数据传递:
this.$Target.on('click', '.anchor', {obj:this}, function(e){
e.preventDefault();
e.data.obj.showMenu();
//some other code
});
或者将它存储在元素上,但是除了声明另外一个变量之外,两者都没有任何不同。