【问题标题】:Why does Backbone.js model's 'on()' take 'this' as last parameter if it's almost always going to be this?为什么 Backbone.js 模型的 'on()' 将 'this' 作为最后一个参数,如果它几乎总是这样?
【发布时间】:2012-10-30 05:07:35
【问题描述】:

我刚刚进入 Backbone,我不明白的一件事是为什么模型的“on()”方法总是需要三个参数——事件、处理程序和上下文。

似乎'this'几乎总是用于上下文,我还没有看到任何其他用法。即使有,因为我还没有见过它,它一定是非常罕见的。

所以我的问题是:什么时候使用“this”以外的上下文,为什么 Backbone 是这样设计的?顺便说一句,我确实理解您为什么需要提供上下文,只是我想知道为什么方法语法指定我使用三个参数而不是使最后一个参数可选 - 这似乎总是“this”并且感觉多余。我确定我错过了一些东西。请有人帮我理解。谢谢!

  • [编辑] 为什么不能做这样的事情:

    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 */
    });
    

【问题讨论】:

    标签: javascript backbone.js this backbone-events


    【解决方案1】:

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

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

    on 调用看到两件事:

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

    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);
      

    无法展开调用堆栈以查看您想要哪个this,因此您必须明确说明。

    Backbone 会这样调用回调:

    node.callback.apply(node.context || this, ...);
    

    其中node.callback 是回调函数,node.context 是给on 的第三个参数(如果有)。如果你不指定上下文,那么当trigger 被调用时,你会得到this 的任何内容;在上面的示例中,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);
    });
    

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

    【讨论】:

    • 感谢您的回答!我不知道这是可选的。让我确保我理解正确。根据您的代码 node.callback.apply(node.context || this, ...);这不意味着默认上下文确实是“this”吗?我不明白你为什么说它不是很有用。
    • 另外,澄清一下,如果我们使用第三个参数 'this',就不需要 _.bindAll(this, ...),这是正确的吗?为什么那么多人在代码中使用 _.bindAll?
    • @Vlad:this 的值始终取决于上下文。当您调用 this.model.on(...) 时,this 与调用 trigger 时的 this 不同。 this 不是变量,它只是看起来像一个。
    • 既然可以使用三个参数on,为什么还要使用_.bindAll?历史?个人喜好?处理不通过 Backbone 的 on 的案例的绑定?
    • 所以基本上第三个参数被绑定到 this.model.on 的闭包中,所以即使在它返回之后,它仍然与 model.on() 时的“this”相关联最初被调用?
    猜你喜欢
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    相关资源
    最近更新 更多