Array.prototype.find()

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2016.

find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined

  • 如果需要在数组中找到对应元素的索引,请使用 findIndex()
  • 如果需要查找某个值的索引,请使用 Array.prototype.indexOf()。(它类似于 findIndex(),但只是检查每个元素是否与值相等,而不是使用测试函数。)
  • 如果需要查找数组中是否存在某个值,请使用 Array.prototype.includes()。同样,它检查每个元素是否与值相等,而不是使用测试函数。
  • 如果需要查找是否有元素满足所提供的测试函数,请使用 Array.prototype.some()

尝试一下

语法

js
find(callbackFn)
find(callbackFn, thisArg)

参数

callbackFn

为数组中的每个元素执行的函数。它应该返回一个真值来表示已经找到了匹配的元素。该函数被调用时将传入以下参数:

element

数组中当前正在处理的元素。

index

正在处理的元素在数组中的索引。

array

调用了 find() 的数组本身。

thisArg 可选

执行 callbackFn 时用作 this 的值。参见迭代方法

返回值

数组中第一个满足所提供测试函数的元素的值,否则返回 undefined

描述

find() 方法是一个迭代方法。它按索引升序顺序为数组中的每个元素调用提供的 callbackFn 函数,直到 callbackFn 返回一个真值。然后 find() 返回该元素并停止迭代数组。如果 callbackFn 从未返回真值,则 find() 返回 undefined

callbackFn 被调用来处理数组的每一个索引,而不仅仅是那些有值的索引。在稀疏数组中,未赋值的空槽与 undefined 表现相同。

find() 不会改变被调用的数组,但是提供给 callbackFn 的函数可能会改变它。但需要注意的是,在第一次调用 callbackFn 之前,数组的长度会被保存。因此:

  • 当调用 find() 时,callbackFn 不会访问超出数组初始长度的任何元素。
  • 对已经访问过的索引的更改不会导致再次在这些元素上调用 callbackFn
  • 如果 callbackFn 改变了数组中已存在但尚未被访问的元素,则传递给 callbackFn 的该元素的值将是该元素在被访问时的值。被删除的元素被视为 undefined

警告: 上述类型的并发修改经常导致难以理解的代码,通常应避免(特殊情况除外)。

find() 方法是通用的。它只期望 this 值具有 length 属性和整数键属性。

示例

在对象数组中通过对象属性进行查找

js
const inventory = [
  { name: "apples", quantity: 2 },
  { name: "bananas", quantity: 0 },
  { name: "cherries", quantity: 5 },
];

function isCherries(fruit) {
  return fruit.name === "cherries";
}

console.log(inventory.find(isCherries));
// { name: 'cherries', quantity: 5 }

使用箭头函数和解构赋值

js
const inventory = [
  { name: "apples", quantity: 2 },
  { name: "bananas", quantity: 0 },
  { name: "cherries", quantity: 5 },
];

const result = inventory.find(({ name }) => name === "cherries");

console.log(result); // { name: 'cherries', quantity: 5 }

寻找数组中的第一个素数

下面的例子展示了如何从数组中寻找素数(如果找不到素数则返回 undefined):

js
function isPrime(element, index, array) {
  let start = 2;
  while (start <= Math.sqrt(element)) {
    if (element % start++ < 1) {
      return false;
    }
  }
  return element > 1;
}

console.log([4, 6, 8, 12].find(isPrime)); // undefined,未找到
console.log([4, 5, 8, 12].find(isPrime)); // 5

在稀疏数组上使用 find()

在稀疏数组中,空槽会被访问的,并被视为 undefined

js
// 声明一个在索引 2、3 和 4 处没有元素的数组
const array = [0, 1, , , , 5, 6];

// 将会打印所有索引,而不仅仅是那些有值的非空槽
array.find((value, index) => {
  console.log(`访问索引 ${index},值为 ${value}`);
});
// 访问索引 0,值为 0
// 访问索引 1,值为 1
// 访问索引 2,值为 undefined
// 访问索引 3,值为 undefined
// 访问索引 4,值为 undefined
// 访问索引 5,值为 5
// 访问索引 6,值为 6

// 打印所有索引,包括已删除的
array.find((value, index) => {
  // 在第一次迭代时删除元素 5
  if (index === 0) {
    console.log(`删除 array[5] 的值 ${array[5]}`);
    delete array[5];
  }
  // 即使删除了,元素 5 仍然被访问
  console.log(`访问索引 ${index},值为 ${value}`);
});
// 删除值为 5 的 array[5]
// 访问索引 0,值为 0
// 访问索引 1,值为 1
// 访问索引 2,值为 undefined
// 访问索引 3,值为 undefined
// 访问索引 4,值为 undefined
// 访问索引 5,值为 undefined
// 访问索引 6,值为 6

在非数组对象上调用 find()

find() 方法读取 thislength 属性,然后访问每个整数索引。

js
const arrayLike = {
  length: 3,
  0: 2,
  1: 7.3,
  2: 4,
};
console.log(Array.prototype.find.call(arrayLike, (x) => !Number.isInteger(x)));
// 7.3

规范

Specification
ECMAScript Language Specification
# sec-array.prototype.find

浏览器兼容性

BCD tables only load in the browser

参见