3

我有一个关于维护对象范围的一般性问题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所以当我进一步深入范围时,我有一个参考。但我觉得这不是最好的方法......有人可以提出更好的选择吗?

4

3 回答 3

1

你正在做的是最好的方法。在 Javascriptthis中是动态范围的(绑定取决于堆栈,即调用函数的位置),所有其他变量 - 都是静态范围的(绑定取决于代码中变量的静态位置)。

而且由于 Javascriptthis以一种特殊的方式处理,因此也不要为以一种特殊的方式处理它而感到难过。

您可以将您现在正在做的事情封装在一个函数中——许多库都提供了这样的工具,它通常被称为“绑定”。但这不会改变真正发生的事情,只会隐藏它(并在执行此操作时消耗一些资源)。这样的函数可能看起来有点像:

function whatever (functionToProcess, thisToFreeze) { 
   return function() {
       functionToProcess.apply(thisToFreeze, arguments); // apply is built in
   }
}
于 2013-04-11T21:36:42.970 回答
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));
    },
于 2013-04-11T21:35:40.543 回答
0

您可以将其作为事件数据传递:

this.$Target.on('click', '.anchor', {obj:this}, function(e){
    e.preventDefault();
    e.data.obj.showMenu();
    //some other code
});

或将其存储在元素上,但与像您一样在外部声明另一个变量并没有什么不同。

于 2013-04-11T21:50:33.033 回答