1

在 Backbone Todo MVC source中,函数的原生apply方法用于调用 Underscore 方法,没有,我不明白为什么它是必要的。

// Filter down the list of all todo items that are finished.
completed: function() {
  return this.filter(function( todo ) {
    return todo.get('completed');
  });
},

// Filter down the list to only todo items that are still not finished.
remaining: function() {
  return this.without.apply( this, this.completed() );
},

与其他 Underscore 方法(例如filter )相比,对without的调用显得格格不入。我仔细检查了 Backbone 源,以确保没有以不同的方式混合到 Collection 对象中。果然,不是。

这就是下划线方法附加到 Collection 的方式:

_.each(methods, function(method) {
  Collection.prototype[method] = function() {
    var args = slice.call(arguments);
    args.unshift(this.models);
    return _[method].apply(_, args);
  };
});

正如所料 - Collection 的模型已经作为第一个参数传递。此外,由于方法是在 Collection 对象上调用的,因此这将是正确的。

我通过将方法更改为以下来验证这一点

this.without(this.completed());

这很好用。

我在这里俯瞰什么?

4

2 回答 2

3

我不认为你忽略了任何事情。这只是对apply. 可能作者最初写了以下内容(可能是早期版本的主干)。

// Filter down the list to only todo items that are still not finished.
remaining: function() {
  return _.without.apply( this, this.completed() );
},
于 2013-11-09T01:29:51.467 回答
2

Underscore's without takes an array as its first argument and a list of values to exclude from the array for the following arguments. In Backbone's case, the array that the undercore methods are working off of is the array of models inside of the collection (collection.models) and the list of values to exclude are the completed todos. So it's essentially

_.without.apply(collection.models, this.completed())

if there is no apply then an array is passed as the second argument to _.without, which would attempt to exclude an array from an array

_.without(collection.models, [completedTodo1, completedTodo2 /* , etc */]);

but with apply, the completed todos are passed as individual arguments ie:

_.without(collection.models, completedTodo1, completedTodo2 /* , etc. */) 

Which is what you want so that it will exclude each completed todo.

于 2013-11-09T01:34:50.040 回答