我刚刚进入Backbone,有一点我不明白为什么模型的'on()'方法总是需要三个参数 - 事件,处理程序和上下文。
似乎几乎总是'this'用于上下文,我还没有看到任何其他用法。即使有,因为我还没有看到它,但它一定非常罕见。
所以我的问题是:什么时候使用除'this'之外的上下文,为什么Backbone会这样设计?顺便说一下,我确实理解为什么你需要提供上下文,这只是我想知道为什么方法语法指定我使用三个参数而不是使最后一个参数可选 - 这似乎总是'这'并且感觉多余。我确定我错过了什么。请有人帮我理解。谢谢!
[编辑]为什么不能做类似的事情:
model.on = function(event, callback){
model.on_with_three_args.call(this, event, callback, this);
});
model.on_with_three_args = function(event, callback){
/* whatever the on() is supposed to do */
});
答案 0 :(得分:9)
假设我们处于一个基于模型的视图中,我们想要绑定到模型的更改事件:
this.model.on('change', this.render);
on
来电看到两件事:
on
无法知道this
中this.render
的含义,只看到一个函数; on
甚至不知道上述呼叫与此之间的区别:
this.model.on('change', function() { ... });
如果您的功能需要特定的上下文,那么您有两个选择:
_.bind
,_.bindAll
,Function.bind
,$.proxy
,CoffeeScripts =>
,var _this = this
关闭技巧或任何创建绑定函数创建或模拟绑定函数的方法。通过说:
告诉您想要的上下文this.model.on('change', this.render, this);
没有办法展开调用堆栈以查看您想要的this
,因此您必须明确它。
Backbone会像这样调用回调:
node.callback.apply(node.context || this, ...);
其中node.callback
是回调函数,node.context
是赋予on
的第三个参数(如果有)。如果你没有指定上下文,那么当你调用this
时,你会得到任何trigger
;在上面的示例中,this
最终将成为模型。
所以on
的第三个参数实际上是可选的,但默认值并不是非常有用,而且无法选择更好的默认值,选择合理上下文所需的信息根本无法访问在JavaScript中。这就是您在Backbone视图中看到如此多_.bindAll(this, ...)
样板的原因。
如果你尝试过这样的话:
model.on = function(event, callback){
model.on_with_three_args.call(this, event, callback, this);
});
那么this
在那种情况下通常是model
,所以你真的会说:
model.on = function(event, callback){
model.on_with_three_args.call(model, event, callback, model);
});
或
model.on = function(event, callback){
model.on_with_three_args(event, callback, model);
});
并且没有任何意义。 this
内on
的值与调用this
的代码中on
的值几乎没有任何关系。 JavaScript中的this
不是变量,它是一个引用当前调用上下文的关键字。