Array.prototype.filter()
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
filter()
方法创建给定数组一部分的浅拷贝,其包含通过所提供函数实现的测试的所有元素。
尝试一下
const words = ["spray", "elite", "exuberant", "destruction", "present"];
const result = words.filter((word) => word.length > 6);
console.log(result);
// Expected output: Array ["exuberant", "destruction", "present"]
语法
filter(callbackFn)
filter(callbackFn, thisArg)
参数
返回值
返回给定数组的一部分的浅拷贝,其中只包括通过提供的函数实现的测试的元素。如果没有元素通过测试,则返回一个空数组。
描述
filter()
方法是一个迭代方法。它为数组中的每个元素调用提供的 callbackFn
函数一次,并构造一个由所有返回真值的元素值组成的新数组。未通过 callbackFn
测试的数组元素不会包含在新数组中。
callbackFn
仅对已分配值的数组索引调用。它不会对稀疏数组中的空槽调用。
filter()
方法是一个复制方法。它不会改变 this
,而是返回一个包含与原始数组相同的元素(其中某些元素已被过滤掉)的浅拷贝。但是,作为 callbackFn
的函数可以更改数组。请注意,在第一次调用 callbackFn
之前,数组的长度已经被保存。因此:
- 当开始调用
filter()
时,callbackFn
将不会访问超出数组初始长度的任何元素。 - 对已访问索引的更改不会导致再次在这些元素上调用
callbackFn
。 - 如果数组中一个现有的、尚未访问的元素被
callbackFn
更改,则它传递给callbackFn
的值将是该元素被修改后的值。被删除的元素则不会被访问。
警告: 上述类型的并发修改经常导致难以理解的代码,通常应避免(特殊情况除外)。
filter()
方法是通用的。它只期望 this
值具有 length
属性和整数键属性。
示例
筛选排除所有较小的值
以下示例使用 filter()
创建一个过滤数组,该数组删除了所有值小于 10
的元素。
function isBigEnough(value) {
return value >= 10;
}
const filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered is [12, 130, 44]
找出数组中所有的素数
下面的例子返回数组中的所有素数:
const array = [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
function isPrime(num) {
for (let i = 2; num > i; i++) {
if (num % i === 0) {
return false;
}
}
return num > 1;
}
console.log(array.filter(isPrime)); // [2, 3, 5, 7, 11, 13]
过滤 JSON 中的无效条目
以下示例使用 filter()
创建具有非零 id
的元素的 json。
const arr = [
{ id: 15 },
{ id: -1 },
{ id: 0 },
{ id: 3 },
{ id: 12.2 },
{},
{ id: null },
{ id: NaN },
{ id: "undefined" },
];
let invalidEntries = 0;
function filterByID(item) {
if (Number.isFinite(item.id) && item.id !== 0) {
return true;
}
invalidEntries++;
return false;
}
const arrByID = arr.filter(filterByID);
console.log("过滤后的数组\n", arrByID);
// 过滤后的数组
// [{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }]
console.log("无效条目数量 =", invalidEntries);
// 无效条目数量 = 5
在数组中搜索
下例使用 filter()
根据搜索条件来过滤数组内容。
const fruits = ["apple", "banana", "grapes", "mango", "orange"];
/**
* 根据搜索条件(查询)筛选数组项
*/
function filterItems(arr, query) {
return arr.filter((el) => el.toLowerCase().includes(query.toLowerCase()));
}
console.log(filterItems(fruits, "ap")); // ['apple', 'grapes']
console.log(filterItems(fruits, "an")); // ['banana', 'mango', 'orange']
在稀疏数组上使用 filter()
filter()
将跳过空槽。
console.log([1, , undefined].filter((x) => x === undefined)); // [undefined]
console.log([1, , undefined].filter((x) => x !== 2)); // [1, undefined]
在非数组对象上调用 filter()
filter()
方法读取 this
的 length
属性,然后访问每个整数索引。
const arrayLike = {
length: 3,
0: "a",
1: "b",
2: "c",
};
console.log(Array.prototype.filter.call(arrayLike, (x) => x <= "b"));
// [ 'a', 'b' ]
影响初始数组(修改、追加和删除)
下面的示例测试在修改数组时 filter()
方法的行为。
// 修改每个单词
let words = ["spray", "limit", "exuberant", "destruction", "elite", "present"];
const modifiedWords = words.filter((word, index, arr) => {
arr[index + 1] += " extra";
return word.length < 6;
});
console.log(modifiedWords);
// 注意,在长度为 6 以下有三个单词,但是由于它们已经被修改,所以返回一个单词
// ["spray"]
// 添加新单词
words = ["spray", "limit", "exuberant", "destruction", "elite", "present"];
const appendedWords = words.filter((word, index, arr) => {
arr.push("new");
return word.length < 6;
});
console.log(appendedWords);
// 只有三个符合条件,即使 `words` 本身现在有更多字符长度小于 6 的单词
// ["spray" ,"limit" ,"elite"]
// 删除单词
words = ["spray", "limit", "exuberant", "destruction", "elite", "present"];
const deleteWords = words.filter((word, index, arr) => {
arr.pop();
return word.length < 6;
});
console.log(deleteWords);
// 注意我们没有得到 'elite',因为它在过滤器访问到它之前就已经从 'words' 弹出了
// ["spray" ,"limit"]
规范
Specification |
---|
ECMAScript® 2025 Language Specification # sec-array.prototype.filter |
浏览器兼容性
BCD tables only load in the browser