3

我正在尝试学习backbone.js 和(通过扩展)underscore.js,但我在理解一些约定时遇到了一些困难。在编写一个简单的搜索过滤器时,我认为像下面这样的东西会起作用:

var search_string = new RegExp(query, "i");

        var results = _.filter(this, function(data){
            return search_string.test(data.get("title"));
        }));

但是,事实上,为了使它工作,我需要将我的过滤器功能更改为以下内容:

var search_string = new RegExp(query, "i");

        var results = _(this.filter(function(data){
            return search_string.test(data.get("title"));
        }));

基本上,我想了解为什么第二个示例有效,而第一个示例无效。根据文档(http://documentcloud.github.com/underscore/#filter),我认为前者会起作用。或者这可能只是反映了我的一些旧的 jQuery 习惯......有人可以为我解释一下吗?

4

2 回答 2

4

我猜您正在使用具有本机Array#filter实现的浏览器。在您的控制台中尝试这些,看看会发生什么:

[].filter.call({ a: 'b' }, function(x) { console.log(x) });
[].filter.call([1, 2],     function(x) { console.log(x) });

第一个不会做任何事情,第二个将产生12作为输出(http://jsfiddle.net/ambiguous/tkRQ3/)。问题不在于data空,问题在于原生Array#filter应用到非数组对象时不知道该做什么。

Underscore 的所有方法(包括filter)都使用本地实现(如果可用):

委托给本机过滤器方法(如果存在)。

_.m(collection, ...)因此,除非您使用不提供本机实现的浏览器,否则Array-ish Underscore 方法通常无法正常工作。

Backbone 集合是模型数组的包装器,模型数组在其中,c.models因此您希望:

_.filter(this.models, function(data) { ... });

Backbone集合混合了几种 Underscore 方法

Underscore.js的 Backbone 代理,在Backbone.Collection上提供 28 个迭代函数。

其中之一是filter。这些代理将 Underscore 方法应用于集合的模型数组,因此c.filter(...)_.filter(c.models, ...).

这种混合可能是混淆 Underscore 正在执行的“我应该使用本机方法”检查的原因:

if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);

您可以_.filter在普通的旧对象 ( ) 上使用并获得合理的结果,但是当您因为集合已经具有下划线方法_.filter({a:'b'}, ...)时它会失败。_.filter(backbone_collection, ...)

这是一个简单的演示,希望能澄清一些事情:http: //jsfiddle.net/ambiguous/FHd3Y/1/

于 2012-05-22T21:44:27.830 回答
-1

出于同样的原因,它$('#element')有效而$#element无效。_是下划线对象的全局变量,就像$是对象的全局变量一样jQuery

_()说看_对象。_filter说寻找一个名为_filter.

于 2012-05-22T20:50:20.883 回答