2012-05-22 102 views
3

我试图Backbone.js的学习和(通过扩展)underscore.js,和我遇到一些困难,了解一些公约。在写一个simpel搜索过滤器,我认为类似下面会的工作: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习惯......任何人都可以为我解释这个吗?

+0

它应该阅读_.filter - 对不起,这是一个错字。使用_.filter数据为空,结果“结果”返回一个空数组。 – bento

+0

而这个''是Backbone集合? –

+0

是的。 (this)的console.log为我提供了一个包含长度,模型等的“孩子”。 – bento

回答

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在应用于非Array对象时不知道该做什么。

所有的下划线的方法(包括filter)使用,如果可用的本地实现:

代表的本土过滤方法,如果它存在。

所以阵列十岁上下的下划线方法一般不会为_.m(collection, ...),除非你使用的浏览器不提供本机实现正常工作。

一个骨干集合是模型的数组的包装,模特阵列在c.models,所以你会想:

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

骨干collections have several Underscore methods混合在:

骨干代理来Underscore.js提供关于Backbone.Collection 28个迭代函数。

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

这种混合式大概是什么迷惑"should I use the native method"会检查下划线是干什么:

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

您可以将普通的旧对象(_.filter({a:'b'}, ...))上使用_.filter,并得到合理的结果,但它没有,当你_.filter(backbone_collection, ...),因为集合已经有Underscore方法。

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

+0

这正是我一直在寻找的东西。感谢您的出色解释。 – bento

-1

出于同样的原因,$('#element')工程和$#element没有。 _是下划线对象的全局变量,就像$jQuery对象的全局变量。

_()说看在_对象。 _filter表示寻找名为_filter的方法。