假设我们处于基于模型的视图中,并且想要绑定到模型的更改事件:
this.model.on('change', this.render);
The on
调用看到两件事:
- 事件名称,一个简单的字符串。
- 处理程序,一个函数。
on
无法知道什么this
意味着在this.render
,它只看到一个函数;on
甚至不知道上面的调用和这个调用之间的区别:
this.model.on('change', function() { ... });
如果您的函数需要特定的上下文,那么您有两种选择:
- 使用创建绑定函数_.bind http://underscorejs.org/#bind, _.bindAll http://underscorejs.org/#bindAll, Function.bind https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind, $.proxy http://api.jquery.com/jQuery.proxy/, 咖啡脚本=> http://coffeescript.org/#fat_arrow, the
var _this = this
闭包技巧,或创建或模拟绑定函数的任何方法。
-
告诉它你想要哪个上下文:
this.model.on('change', this.render, this);
没有办法展开调用堆栈来查看哪个this
你想要,所以你必须明确地表达出来。
Backbone 将像这样调用回调:
node.callback.apply(node.context || this, ...);
where node.callback
是回调函数并且node.context
是第三个参数(如果有)on
。如果您不指定上下文,那么您将得到任何内容this
恰好是当trigger
叫做;在上面的例子中,this
最终会成为模型。
所以第三个参数on
实际上是可选的,但默认值并不是很有用,而且没有办法选择更好的默认值,选择合理上下文所需的信息在 JavaScript 中根本无法访问。这就是为什么你看到这么多_.bindAll(this, ...)
主干视图中的样板。
如果你尝试过这样的事情:
model.on = function(event, callback){
model.on_with_three_args.call(this, event, callback, this);
});
then this
在这种情况下通常会是model
所以你真的会说:
model.on = function(event, callback){
model.on_with_three_args.call(model, event, callback, model);
});
or
model.on = function(event, callback){
model.on_with_three_args(event, callback, model);
});
这些都毫无意义。的价值this
inside on
与价值几乎没有关系this
在调用的代码中on
. this
在 JavaScript 中不是一个变量,它是一个关键字,引用当前的调用上下文。