Array.prototype.findLast()
==========================

**`findLast()`** は `Array` インスタンスのメソッドで、配列を逆順に反復処理し、指定されたテスト関数を満たす最初の要素の値を返します。
 テスト関数を満たす要素がない場合は `undefined` が返されます。

検索を行う場合は以下のメソッドが必要です。

* 一致する最初の要素を得るには、 `find()` を使用してください。
* 配列内で一致する最後の位置を得るには、 `findLastIndex()` を使用してください。
* 値の位置を得るには、 `indexOf()` を使用してください。
 （これは `findIndex()` に似ていますが、テスト関数を使用するのではなく、それぞれの要素が値と等しいかどうかを調べます。）
* 配列に値が存在するかどうかを調べるには、 `includes()` を使用してください。
 こちらも、テスト関数を使用する代わりに、各要素が値と等しいかどうかを調べます。
* 指定されたテスト関数を満たす要素を得るには `some()` を使用してください。
試してみましょう
--------

構文
--


```js
findLast(callbackFn)
findLast(callbackFn, thisArg)
```

### 引数

`callbackFn`

配列のそれぞれの要素に対して実行する関数です。一致する要素が得られたことを示すには真値を返し、そうでなければ偽値を返してください。この関数は以下の引数で呼び出されます。

`element`

配列内で現在処理されている要素です。

`index`

配列内で現在処理されている要素のインデックス（位置）です。

`array`

`findLast()` を呼び出した元の配列です。


`thisArg` 省略可

`callbackFn` 内で `this` として使われるオブジェクトです。反復処理メソッドを参照してください。

### 返値

指定されたテスト関数を満たす、配列中の最も大きいインデックス値を持つ要素の値。一致する要素が見つからない場合は `undefined` となります。

解説
--

`findLast()` メソッドは反復処理メソッドです。配列の要素のそれぞれに対して、インデックスの降順に一度ずつ `callbackFn` 関数を実行し、`callbackFn` 関数が真値を返すまで繰り返します。 `findLast()` はその要素を返し、配列の反復処理を停止します。もし `callbackFn` が真値を返さない場合、 `find()` は `undefined` を返します。

`callbackFn` は、値が割り当てられているものに限らず、配列中の*すべて*のインデックスに対して呼び出されます。疎配列では、空のスロットは `undefined` と同じ動作をします。

`findLast()` は、呼び出した配列を変更 (mutate) しませんが、`callbackFn` で提供された関数は変更する可能性があります。しかし、配列の長さは最初に `callbackFn` が呼び出される*前に*設定されます。したがって、

* `callbackFn` は `findLast()` の呼び出しを始めたときの配列の長さを超えて追加された要素にはアクセスしません。
* 既に訪問した位置を変更しても、 `callbackFn` が再度呼び出されることはありません。
* まだ訪問していない既存の配列要素が `callbackFn` によって変更された場合、 `callbackFn` に渡される値はその要素が取得される時点の値になります。削除された 要素は `undefined` であるかのように処理されます。

**警告:** 前項で説明したような、参照中の配列の同時進行での変更は（特殊な場合を除いて）普通は避けるべきです。多くの場合、理解しにくいコードになります。

`findLast()` メソッドは汎用的です。これは `this` 値に `length` プロパティと整数キーのプロパティがあることだけを期待します。

例
-

### 要素のプロパティに一致する配列の最後のオブジェクトを探す

この例では、配列要素のプロパティに基づいたテストを作成する方法を示します。


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

// 在庫がない場合は真値を返す
function isNotEnough(item) {
  return item.quantity < 2;
}

console.log(inventory.findLast(isNotEnough));
// { name: "fish", quantity: 1 }
```


#### アロー関数と分割代入の使用

先の例は、アロー関数とオブジェクトの分割代入を使用して書くことができるかもしれません。


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

const result = inventory.findLast(({ quantity }) => quantity < 2);

console.log(result);
// { name: "fish", quantity: 1 }
```

### 配列中の最後の素数を探す

以下の例では、配列の最後の要素で素数の最後の要素を返します。素数がない場合は `undefined` を返しています。


```js
function isPrime(element) {
  if (element % 2 === 0 || element < 2) {
    return false;
  }
  for (let factor = 3; factor <= Math.sqrt(element); factor += 2) {
    if (element % factor === 0) {
      return false;
    }
  }
  return true;
}

console.log([4, 6, 8, 12].findLast(isPrime)); // undefined, not found
console.log([4, 5, 7, 8, 9, 11, 12].findLast(isPrime)); // 11
```

### 存在しない要素や削除された要素に対しても呼び出される

疎配列の空のスロットは処理され、 `undefined` と同じように扱われます。


```js
// インデックス 2、3、4 に要素がない配列の宣言
const array = [0, 1, , , , 5, 6];

// 値が割り当てられているインデックスだけでなく、すべてのインデックスを表示
array.findLast((value, index) => {
  console.log(`Visited index ${index} with value ${value}`);
});
// Visited index 6 with value 6
// Visited index 5 with value 5
// Visited index 4 with value undefined
// Visited index 3 with value undefined
// Visited index 2 with value undefined
// Visited index 1 with value 1
// Visited index 0 with value 0

// 削除されたインデックスを含め、すべてのインデックスを表示
array.findLast((value, index) => {
  // Delete element 5 on first iteration
  if (index === 6) {
    console.log(`Deleting array[5] with value ${array[5]}`);
    delete array[5];
  }
  // 要素 5 は削除されたにもかかわらず、処理される
  console.log(`Visited index ${index} with value ${value}`);
});
// Deleting array[5] with value 5
// Visited index 6 with value 6
// Visited index 5 with value undefined
// Visited index 4 with value undefined
// Visited index 3 with value undefined
// Visited index 2 with value undefined
// Visited index 1 with value 1
// Visited index 0 with value 0
```

### 配列でないオブジェクトに対する findLast() の呼び出し

`findLast()` メソッドは `this` の `length` プロパティを読み込み、次にキーが `length` より小さい非負の整数である各プロパティにアクセスします。


```js
const arrayLike = {
  length: 3,
  0: 2,
  1: 7.3,
  2: 4,
  3: 3, // length が 3 なので findLast() は無視される
};
console.log(
  Array.prototype.findLast.call(arrayLike, (x) => Number.isInteger(x)),
); // 4
```

仕様書
---

| Specification |
| --- |
| ECMAScript Language Specification # sec-array.prototype.findlast |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* `Array.prototype.findLast` のポリフィル (`core-js`)
* インデックス付きコレクションのガイド
* `Array`
* `Array.prototype.find()`
* `Array.prototype.findIndex()`
* `Array.prototype.findLastIndex()`
* `Array.prototype.includes()`
* `Array.prototype.filter()`
* `Array.prototype.every()`
* `Array.prototype.some()`
* `TypedArray.prototype.findLast()`