【问题标题】:Backbone.js - Todo Collection - What exactly is happening in this return statement?Backbone.js - Todo Collection - 这个返回语句到底发生了什么?
【发布时间】:2012-02-04 00:42:09
【问题描述】:

我正在查看 Backbone 待办事项列表,并有一个关于集合的问题。

代码如下:

window.TodoList = Bacbone.Collection.extend({

        model: Todo,

        localStorage: new Store("todos"),

        done: function() {
            return this.filter(function(todo){return todo.get("done")})
        },

        remaining: function() {
            return this.without.apply(this, this.done());
        }



    })

我了解这里发生的一切,除了“剩余”功能。

返回语句:return this.without.apply(this, this.done()); 正在使用下划线方法的代理 - _.without

根据下划线文档,这是为了:

without_.without(array, [*values]) 返回数组的副本 值的所有实例均已删除。 === 用于相等 测试。

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); => [2, 3, 4]

所以,我知道它是说返回集合中的所有内容,而没有值为 'true' 的 'done' 属性。

我不明白的是链接到它的“应用”功能。这不会出现在 Backbone 文档或 Underscore 文档中。至少在我能找到的任何地方都找不到。

谁能详细解释一下 Return 声明中的这些元素是怎么回事?

【问题讨论】:

    标签: javascript jquery backbone.js underscore.js


    【解决方案1】:

    this 指的是集合。

    apply 是 javascript 函数的方法,允许您设置方法的上下文并将值数组发送给调用者。

    apply 期望上下文作为第一个参数,然后是 array 或 类数组(例如 arguments),它们将作为参数传递给函数。

    你可以用.call 做同样的事情,除了第二个+参数用逗号分隔。

    apply 和 call 是 JavaScript 原生的。

    所以……

    return this.without.apply(this, this.done());

    this.done() 方法返回一个数组,但使用集合的上下文并通过without 方法传入一系列要忽略的值。依次返回集合中未完成的所有待办事项。

    例子:

    _.without([1,2,3,4],1,2); === _.without.call([], [1,2,3,4], 1, 2);
    

    【讨论】:

    • 谢谢。我不明白的部分是函数without 有它自己的方法。所以apply(和call)是without函数的方法。它们用于调用函数,就好像它是另一个对象的方法一样。我很确定,正如@j4w7 在下面指出的那样,在这种情况下,它实际上是多余的,因为without 的this 已经绑定到this。所以任何时候你看到this.fn.apply(this,...) === this.fn(...),除非你有理由相信fn的this已经被bind/bindAll改变了。
    • 就我而言,这与“this”的绑定无关——它是一种(有点笨拙)的方式来传递 without() 应该删除的值数组。 “without()”希望将应该作为参数删除的值。并且使用 apply(thisValue,argumentArray),数组的内容作为参数传递,而不是作为数组本身。
    【解决方案2】:

    我的理解是,在这种情况下,apply 的使用是多余的,remaining 可以缩短如下:

    remaining: function() {
      return this.without(this.done());
    }
    

    据我了解,使用apply 的唯一原因是如果您想要(或需要)更改without 将操作的上下文项。在这种情况下,我们不需要这样做。

    如果我错了,我真的(真的!)想解释一下为什么这里需要apply。

    【讨论】:

      【解决方案3】:

      apply 调用一个函数并将该函数上下文中的 this 绑定到传递的第一个参数(在本例中为 Collection 实例 TodoList)。第二个参数是要传递给without 的参数数组。

      顺便说一句,apply 不是 Backbone 的东西——它是 JavaScript 原生的。

      【讨论】:

        【解决方案4】:

        原因

        this.without.apply(this, this.done())

        “_.without”不接受作为单个数组([])参数排除的项目数组作为参数

        请看这里_.without to accept array as second argument

        apply,它是 JS Function.prototype 的一部分,这里是在单个数组参数中注入排除项的解决方法

        【讨论】:

          【解决方案5】:

          在这种情况下使用 apply 是多余的,因为骨干集合正在正确地完成这项工作。 http://backbonejs.org/docs/backbone.html#section-122

          我们可以像这样使用下划线:_.without.apply(this, this.done()) 或这样的主干绑定:this.without(this.done) 通过使用主干绑定。

          【讨论】:

            【解决方案6】:

            请查看下划线文档: 像这样:

            without_.without(array, [*values]) 返回删除所有值实例的数组副本。

            _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); => [2, 3, 4]

            【讨论】:

              【解决方案7】:

              我把函数改成了这个,在 TODO 列表应用程序上得到了完全相同的结果:

              remaining: function () {
                      return this.filter(function (todo) {
                          return !todo.get('done');
                      });
              }
              

              我仍然不明白 apply 是如何成为 without 的方法,我知道 apply 是一个 Javascript 函数,但后来我阅读了documentation for apply 并明白在这种情况下,with 是以面向对象的方式使用的(见http://underscorejs.org/#chain)。

              事实上,apply 可以传递 null 而不是 this 作为上下文,它不会改变结果,因为它不是完全用过:

              return this.without.apply(null, this.done());
              

              注意第一个 this 是模型的实际集合,而 没有,通过 apply 中的第二个参数,它是 done 的数组(已完成)任务,正在生成待办事项数组。

              顺便说一句,最新版本的 TODO 应用程序将函数 done 重命名为 completed。

              【讨论】:

                【解决方案8】:

                这里 this.without() 委托给 _.without() 函数。 _.without() 需要一个数组和元素作为参数而不是数组。通过使用 apply() ,以正确的方式应用调用 _.without() 。

                var obj = {
                    f1: function(a,b,c){}
                };
                
                Now obj.f1(1,2,3) == obj.f1.apply(obj, [1,2,3]).
                

                有了这个信息,this.without(this.complete()) 将一个数组传递给 without 方法。但是如果没有方法,则需要将单个元素作为参数传递。这可以使用 Function.apply() 来完成。

                【讨论】:

                  【解决方案9】:

                  without 函数需要从this 中删除的元素列表。 this.completed() 返回一个数组,因此它不是 without 函数所期望的。

                  apply 是一个原生 JavaScript 函数,它调用一个将 this 上下文设置为第一个参数并将数组设置为第二个参数的函数。该参数作为其列表参数传递给原始函数。

                  在这种情况下apply 将参数传递给this.completed() 中的without,满足without 的期望。

                  总之,在这种情况下,apply 是必要的。

                  【讨论】:

                    【解决方案10】:

                    对不起,我完全是新手@这个东西,但不能 fn.remaining (also) 被声明为:

                    return this.filter(function(todo){return !todo.get("done")})

                    将此声明为澄清请求,而不是替代声明:)

                    (编辑:不能在 'todo.get...' 之前加粗 '!')

                    【讨论】:

                      猜你喜欢
                      • 2013-11-29
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-08-29
                      • 2021-03-18
                      • 2019-11-05
                      • 1970-01-01
                      • 2015-12-03
                      相关资源
                      最近更新 更多