Array.filter与$filter('filter')的区别

4

在Angular应用中,我应该使用哪一个并解释原因?

array.filter(o => o.name === myName);

或者
$filter('filter')(array, {name: myName}, true);
3个回答

4
关键区别在于$filter('filter')提供的快捷方式或语法糖。例如,可以使用以下语法来获取包含关键字字符串的项中的任何一个项的字符串属性:
$filter('filter')(array, 'keyword')

使用标准的ES5 Array.prototype.filter不能如此简单。

虽然两种方法的一般思想相同 - 返回给定数组的子集作为数组。

更新:

在幕后,Angular使用Array.prototype.filter

function filterFilter() {
    // predicateFn is created here...

    return Array.prototype.filter.call(array, predicateFn);
}

因此,如果您不使用快捷方式,angular 只是将调用委派给标准 filter

回答你的问题:使用让您编写更少代码的那个。在您的特定情况下,它将是 array.filter(o => o.name === myName);


如果我没记错的话,$filter('filter') 似乎也对所有属性执行 LIKE 检查,这比等值谓词检查要强大得多。(对于 OP 的情况来说,有点过度杀伤力) - kazenorin
@kazenorin,如果你将true作为comparator参数传递,Angular将使用angular.equals进行严格比较。 - Alexander Kravets

2
使用Array.filter而不是$filter('filter')有四个好理由: 效率 虽然$filter('filter')在使用Array.filter的同时还使用其他代码,包括深度比较,但在大多数情况下速度差异微不足道,但在某些用例中可能会有很大的差异。例如,在处理大型数据对象时,使用Array.filter会有所帮助。 Angular 2+不支持AngularJS风格的过滤器angular迁移指南中可以看到:

内置的AngularJS filter和orderBy filter在Angular中不存在,因此您需要自行进行过滤和排序。

如果未来可能升级到Angular 2或更高版本,则使用Array.filter将为您节省一些迁移问题。即使您没有计划升级,显然Angular团队认为AngularJS过滤器不值得保留,这让我认为最好还是避免使用它。 优先使用本地代码而不是库代码 像AngularJS这样的库和框架是令人惊异的工具;但是,如果必须选择使用原始JavaScript或使用库,并且没有使用库的好理由,您应该始终使用原始JavaScript。它更广泛地被理解,不那么依赖第三方代码等。有大量的在线文章支持这一点。 "$filter"抑制Typescript文件中的类型检查 这仅适用于使用(或计划使用)Typescript的情况。在撰写本文时,angularjs的@types库将所有$filter函数的返回类型定义为any,如果您不小心,可能会导致一些严重的类型检查问题。相比之下,Array.filter始终返回预期的数组类型。

1
"Angular 2+不支持AngularJS风格的过滤器...如果你必须在使用原生JavaScript和使用库之间做出选择,并且没有充分的理由使用库,那么你应该始终使用原生JavaScript。""100%正确。一个会将你的业务逻辑紧密耦合到AngularJS上,而另一个是原生JavaScript,可以使相同的代码[最大化]未来兼容性。" - ruffin

-1
你应该使用 Array.filter 并分配结果。当你使用 $filter 时,它会在每个绑定的$digest周期结束时重新应用到所有绑定上,这对于监视值并在每个$digest周期后更新结果来说是性能密集的。相反,你应该显式地过滤结果并将其分配给你的作用域变量。

这意味着当我将数组过滤的结果分配到某个地方,然后修改我的数组时,对过滤后的数组的引用不会被更新? - H W
是的。使用 array.filter 会有一些样板代码,但性能更好。您需要在“性能”与“代码简洁性”之间进行权衡决策。 - Aditya Singh
2
错误,$filter 不会创建一个监视器。 - Dieterg
@Dieterg 更新了措辞。我实际上的意思是,在每个 $digest 循环之后它会被重新应用。 - Aditya Singh
3
除非您启用了$stateful标志,否则过滤器不会在每个$digest周期后应用(仅适用于在HTML模板中使用过滤器的情况)。如果您在控制器中使用$filter(除非您处于$watch中),则不会发生这种情况。但是,明确一点,我同意在这种情况下最好使用Array.filter - Dieterg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接