为什么Backbone.js模型的'on()'将'this'作为最后一个参数,如果它几乎总是这样?

Vla*_*lad 3 javascript this backbone.js backbone-events

我刚刚进入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 */
    });
    
    Run Code Online (Sandbox Code Playgroud)

mu *_*ort 9

假设我们处于基于模型的视图中,并且我们想要绑定到模型的更改事件:

this.model.on('change', this.render);
Run Code Online (Sandbox Code Playgroud)

on呼叫看到两件事情:

  1. 事件名称,一个简单的字符串.
  2. 处理程序,一个函数.

on无法知道什么this意思this.render,它只是看到一个功能; on甚至不知道上面的呼叫与此之间的区别:

this.model.on('change', function() { ... });
Run Code Online (Sandbox Code Playgroud)

如果您的函数需要特定的上下文,那么您有两个选择:

  1. 创建使用绑定功能_.bind,_.bindAll,Function.bind,$.proxy,CoffeeScripts =>,该var _this = this关闭的把戏,或者任何的创建或模拟绑定功能的方式.
  2. 通过说出来告诉它你想要的上下文:

    this.model.on('change', this.render, this);
    
    Run Code Online (Sandbox Code Playgroud)

没有办法展开调用堆栈以查看this您想要的内容,因此您必须明确它.

Backbone会像这样调用回调函数:

node.callback.apply(node.context || this, ...);
Run Code Online (Sandbox Code Playgroud)

node.callback回调函数在哪里,是node.context给定的第三个参数(如果有的话)on.如果你没有指定上下文,那么你将获得调用this时发生的任何事情trigger; 在上面的例子中,this最终将成为模型.

所以on实际的第三个参数是可选的,但是默认值并不是非常有用,并且没有办法选择更好的默认值,选择合理上下文所需的信息根本无法在JavaScript中访问.这就是你_.bindAll(this, ...)在Backbone视图中看到如此多样板的原因.


如果您尝试过这样的事情:

model.on = function(event, callback){
    model.on_with_three_args.call(this, event, callback, this);
});
Run Code Online (Sandbox Code Playgroud)

那么this在这种情况下通常是model这样你真的会说:

model.on = function(event, callback){
    model.on_with_three_args.call(model, event, callback, model);
});
Run Code Online (Sandbox Code Playgroud)

要么

model.on = function(event, callback){
    model.on_with_three_args(event, callback, model);
});
Run Code Online (Sandbox Code Playgroud)

并且没有任何意义.如果与调用的代码中的值有任何关系,则thisinside 的值on几乎没有.在JavaScript中不是变量,它是一个引用当前调用上下文的关键字.thisonthis