ECMAScript 5.1 规范的第 15.4.4.20 节定义Array.prototype.filter(callbackfn, thisArg)
如下:
callbackfn
应该是一个函数,它接受三个参数并返回一个可强制转换为布尔值的值true
或
false
. 对数组中的每个元素按升序filter
调用一次,并构造一个包含所有返回值的新数组。仅对实际存在的数组元素调用;它不需要数组的缺失元素。callbackfn
callbackfn
true
callbackfn
如果thisArg
提供了参数,它将用作this
每次调用的值callbackfn
。如果未提供,
undefined
则改为使用。
callbackfn
使用三个参数调用:元素的值、元素的索引和被遍历的对象。
filter
不会直接改变调用它的对象,但对象可能会通过调用callbackfn
.
filter 处理的元素范围是在第一次调用之前设置的callbackfn
。在调用过滤器开始后附加到数组的元素将不会被callbackfn
. 如果数组的现有元素被更改,它们传递给
callbackfn
的值将是过滤器访问它们时的值;在调用过滤器开始之后和被访问之前被删除的元素不会被访问。
这本身就已经是很多工作了。ECMAScript 引擎需要执行的许多步骤。
然后它继续说以下内容:
当使用一个或两个参数调用过滤器方法时,将执行以下步骤:
让O
是调用ToObject
将this
值作为参数传递的结果。让是使用参数lenValue
调用[[Get]]
内部方法的结果。让_O
length
len
ToUint32(lenValue)
. 如果 IsCallable(callbackfn) 为 false,则抛出 TypeError 异常。如果提供了 thisArg,则令 T 为 thisArg;否则令 T 未定义。让 A 是一个新数组,就像由表达式 new Array() 创建的,其中 Array 是具有该名称的标准内置构造函数。令 k 为 0。令为 0。重复,而 k < len 令 Pk 为 ToString(k)。令 kPresent 为使用参数 Pk 调用 O 的 [[HasProperty]] 内部方法的结果。如果 kPresent 为真,则令 kValue 为使用参数 Pk 调用 O 的 [[Get]] 内部方法的结果。令 selected 为调用 callbackfn 的 [[Call]] 内部方法的结果,其中 T 作为 this 值,参数列表包含 kValue、k 和 O。如果 ToBoolean(selected) 为 true,则调用 [[DefineOwnProperty]] A 的内部方法,带参数 ToString(to),属性描述符 {[[Value]]: kValue, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true} 和 false。增加 1。将 k 增加 1。返回 A。
filter方法的length属性为1。
注意过滤器功能是故意通用的;它不要求它的 this 值是一个 Array 对象。因此,它可以转移到其他类型的对象中用作方法。过滤器功能是否可以成功应用于宿主对象取决于实现。
关于这个算法的一些注意事项:
- 它可以防止谓词函数改变数据
- 它可以选择设置谓词函数的执行上下文
- 它忽略数组中已删除的值和间隙
在很多情况下,这些东西都不需要。因此,在编写filter
自己的方法时,大多数时候您甚至都不会费心执行这些步骤。
每个符合 ES5.1 的 JavaScript 引擎都必须符合该算法,因此每次使用Array#filter
.
任何只执行部分步骤的自定义编写方法都会更快,这不足为奇:)
如果您编写自己的filter
函数,它可能不会像上述算法那样复杂。也许您根本不会将数组转换为对象,因为根据用例,可能不需要仅过滤数组。