【问题标题】:Array.filter vs $filter('filter')Array.filter 与 $filter('filter')
【发布时间】:2016-10-26 17:50:54
【问题描述】:

我应该在 Angular 应用中使用哪一个?为什么?

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

$filter('filter')(array, {name: myName}, true);

【问题讨论】:

    标签: javascript arrays angularjs filter angularjs-filter


    【解决方案1】:

    您应该使用Array.filter,然后分配结果。当您使用 $filter 时,它会在每个 $digest 循环结束时重新应用于所有绑定,并且在每个 之后监视值和更新结果会占用大量性能$digest 循环。相反,您应该过滤结果并将其显式分配给您的范围变量

    【讨论】:

    • 这意味着当我将array.filter的结果分配到某处然后修改我的数组时,对过滤数组的引用不会被更新?
    • 是的。使用array.filter 有点mpre 样板,但性能更好。您需要在 performancecode conciseness 之间做出权衡
    • 错误,$filter 不会创建手表。
    • @Dieterg 更新了措辞。我的真正意思是它在每个$digest 周期后重新应用
    • 错误,过滤器不会在每个 $digest 循环后应用(除非您启用了 $stateful 标志。这也仅适用于在您的 HTML 模板中使用过滤器。如果你在controller 中使用$filter(除非你在$watch ofcrouse 中)。但要明确的是,我同意在这种情况下最好使用Array.filter
    【解决方案2】:

    主要区别在于$filter('filter') 提供的快捷方式或语法糖。例如,以下语法可用于获取项目的任何 string 属性中包含 keyword 字符串的项目:

    $filter('filter')(array, 'keyword')
    

    这不是使用标准 ES5 Array.prototype.filter 这么简单。

    而这两种方法的总体思路是相同的 - 将给定数组的子集作为 NEW 数组返回。

    更新

    Under the hood 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);

    【讨论】:

    • IIRC, $filter('filter') 似乎也对所有属性执行 LIKE 检查,这比相等谓词检查强大得多。 (对于 OP 的情况来说,这是矫枉过正)
    • @kazenorin,如果您将true 作为comparator 参数传递,角度将使用angular.equals 进行严格比较。
    【解决方案3】:

    虽然使用 $filter('filter') 可能更容易且在语法上更具吸引力,但我可以想到四个使用 Array.filter 而不是 $filter('filter') 的好理由

    效率

    虽然 $filter('filter') 确实在底层使用了 Array.filter,但除了 Array.filter 之外,它还使用了其他代码,包括深度比较。在大多数情况下,速度差异可以忽略不计,但在某些用例中可能很大。例如,在处理大型数据对象时,我发现使用 Array.filter 会有所不同。

    Angular 2+ 不支持 AngularJS 样式的过滤器

    来自angular migration guide

    AngularJS 内置过滤器和 orderBy 过滤器不存在 Angular,所以你需要自己做过滤和排序。

    如果您将来有可能升级到 Angular 2 或更高版本,那么使用 Array.filter 将为您节省一些迁移偏头痛。即使您不打算升级,显然 Angular 团队也不认为 AngularJS 过滤器值得保留,这让我认为最好还是避免使用它。

    优先使用本机代码而不是库代码

    像 AngularJS 这样的库和框架是很棒的工具;但是,如果您必须在使用 vanilla javascript 或使用库之间进行选择,并且没有充分的理由使用该库,您应该始终使用 vanilla javascript。更普遍理解,较少依赖 3rd 方代码等。网上有大量文章争论这一点。

    "$filter" 禁止在 Typescript 文件中进行类型检查

    仅当您使用(或计划使用)Typescript 时才适用。在撰写本文时,angularjs 的 @types 库将所有​​ $filter 函数的返回类型定义为 any,如果您不小心,可能会导致一些严重的类型检查问题。相比之下,Array.filter 总是返回预期的数组类型。

    【讨论】:

    • "Angular 2+ 不支持 AngularJS 样式的过滤器...如果您必须在使用原生 javascript 或使用库之间进行选择,并且没有充分的理由使用库,您应该始终使用原版 javascript。" 100% 这个。一个将您的业务逻辑与 AngularJS 紧密耦合。另一种是 vanilla JavaScript,它允许相同的代码 [最大程度] 面向未来。
    猜你喜欢
    • 2011-10-17
    • 2013-05-31
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    • 2015-05-14
    相关资源
    最近更新 更多