在回调函数中保留“this”的值

3

我不确定这个问题是否只涉及Backbone.js。我有一个带有以下渲染函数的模型:

render: function() { 
    var self = this;
    this.$el.empty();
    this.model.fetch({
        success: function() {
            self.$el.append(self.template(self.model.attributes));      
        }
    });

    return this;
}

如您所见,在success回调函数内,我使用了一个名为self的变量。这是因为在回调函数内部,this被设置为window,而我想要它被设置为视图。有没有一种方法可以在不存储它在另一个变量中的情况下保留this的原始引用?


对于没有内部回调的小回调,您可以使用function.prototype.bind(或类似的替代方法),但对于更大的代码块,我建议坚持使用“self”或“that”,因为这些词法作用域变量即使在嵌套回调中也会继续工作。 - hugomg
2个回答

6
使用Function.prototype.bind函数将您的对象绑定到函数内的this变量。
render: function() { 
    this.$el.empty();
    var successFunc = function() { 
                 this.$el.append(this.template(this.model.attributes));      
    };

    this.model.fetch({
        success: successFunc.bind(this)
        }
    });

    return this;
}

2
bind 不向后兼容,而 $.proxy 是。 - zzzzBov
1
好的观点。我会留下我的答案,供那些不使用jQuery的开发人员参考。请注意,如果您不想使用提供bind功能的库,MDN链接中提供了足够简单的实现方法。 - Chris Hayes
1
@zzzzBov:但在 Backbone 应用程序中,使用 _.bind 更符合惯例。 - mu is too short
@muistooshort,我认为_.bind$.proxy同样符合惯用法。这真的取决于你是来自underscore世界还是来自jQuery世界。由于事件绑定的处理方式,我倾向于使用$.proxy,但在类初始化的一部分中调用bindAll也非常方便。 - zzzzBov
希望我能给你们两个人都最佳答案。这是一个非常全面的解释/讨论,现在我对如何使用bind有了更好的理解。 - user2066880
它的核心是使用jQuery(甚至是Zepto),所以$.proxy方法是可用的。 - kinakuta

6

有没有一种方法可以在不将其存储在另一个变量中的情况下保留它的原始引用?

是的,这是proxy 方法的一个合理使用案例。

this.model.fetch({
    success: $.proxy(function() {
        this.$el.append(this.template(this.model.attributes));      
    }, this)
});

另外,您还可以使用下划线的 bind 方法:

this.model.fetch({
    success: _.bind(function() {
        this.$el.append(this.template(this.model.attributes));      
    }, this)
});

1
使用$.proxy,您不再需要self了。在成功回调中使用this。 - gp.
“self”这样的名称非常糟糕,因为存在“window.self”。 - mu is too short
2
@muistooshort,实际上self是一个非常好的选择。它很常见且描述准确。仅仅因为window有一个默认属性self并不意味着你不能在其他作用域中使用self - zzzzBov
一个简单的缺失 var self = this 可能会导致令人困惑的错误,通过使用不同的名称可以轻松避免这种情况。 - mu is too short
2
@muistooshort,加上"use strict",你就不会遇到那个问题了。 - zzzzBov
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接