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

时间:2012-10-30 05:07:36

标签: javascript backbone.js this 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 */
    });
    

1 个答案:

答案 0 :(得分:9)

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

this.model.on('change', this.render);

on来电看到两件事:

  1. 事件名称,一个简单的字符串。
  2. 处理程序,一个函数。
  3. on无法知道thisthis.render的含义,只看到一个函数; on甚至不知道上述呼叫与此之间的区别:

    this.model.on('change', function() { ... });
    

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

    1. 使用_.bind_.bindAllFunction.bind$.proxy,CoffeeScripts =>var _this = this关闭技巧或任何创建绑定函数创建或模拟绑定函数的方法。
    2. 通过说:

      告诉您想要的上下文
      this.model.on('change', this.render, this);
      
    3. 没有办法展开调用堆栈以查看您想要的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);
      });
      

      并且没有任何意义。 thison的值与调用this的代码中on的值几乎没有任何关系。 JavaScript中的this不是变量,它是一个引用当前调用上下文的关键字。