JavaScriptの新機能2023年版 - コード例を交えた変更点

# 初めに
こんにちは、株式会社エアークローゼットでエンジニアをしているCloudと申します。

この記載は[エアークローゼットのアドベントカレンダー2023](https://qiita.com/advent-calendar/2023/air-closet)の22日目の記事になります。
今回はJavaScriptの新機能2023年版とコード例について紹介したいと思います。

以下はECMAScript2023における言語の第14版でおこなわた素晴らしい変更点です。
これらの変更はプログラミングライフをより簡単になるかもしれないので興味があればぜひ最後までご覧でください。
# 詳しく
以下は新しい変更点の３つで説明します。まずはObject.groupByです。
### Object.groupBy
例えば、オブジェクトの配列があり、それをプロパティの値、型、または数量に基づいて分割したいとしましょう。
```js
const inventory = [
  { name: "asparagus", type: "vegetables", quantity: 5 },
  { name: "bananas", type: "fruit", quantity: 0 },
  { name: "goat", type: "meat", quantity: 23 },
  { name: "cherries", type: "fruit", quantity: 5 },
  { name: "fish", type: "meat", quantity: 22 },
];
```
これを行うため`GroupBy`として簡単に行えて新しいメソッドがあります。
利用するには、オブジェクトを含む任意の配列で`Object.groupBy`を利用し、分類したい特定のキーを変える関数を渡します。

ここでは、`inventory`と呼ばれるオブジェクトの配列があります。そして`quantity`をパラメーターとして受け取り、数量が5より大きい場合は`OK`を返し、それ以外の場合は`restock`を返す`myCallback`関数があります。

`inventory`と`myCallback`を`Object.groupBy`に渡すうことで配列のアイテムを数量でグループ化します。
```js
function myCallback({ quantity }) {
  return quantity > 5 ? "ok" : "restock";
}

const result2 = Object.groupBy(inventory, myCallback);
```

結果は、カテゴリを示すキーとその内部に指定されたデータを含むオブジェクトになります。

```js
{
    "restock": [
        {
            "name": "asparagus",
            "type": "vegetables",
            "quantity": 5
        },
        {
            "name": "bananas",
            "type": "fruit",
            "quantity": 0
        },
        {
            "name": "cherries",
            "type": "fruit",
            "quantity": 5
        }
    ],
    "ok": [
        {
            "name": "goat",
            "type": "meat",
            "quantity": 23
        },
        {
            "name": "fish",
            "type": "meat",
            "quantity": 22
        }
    ]
}

```
### Array.toSliced(), Array.toSorted(), and Array.toReversed()
Arrayのメソッドを初めとして`sort()`、`splice()`及び`reverse()`のようなメソッドがよく使われますが利用すると元の配列が変更されます。そして、これは時折問題になることがあります。

この問題を防止するため`toSpliced()`、`toSorted()`、および `toReversed()` を使用すると、ソース配列を変更せずに配列をスプライス、ソート、および逆順にすることができます。以下にその動作を示します。

```js
const numbers = [3, 4, 1, 5, 2];

const splicedNumbers = numbers.toSpliced(1, 1);
const sortedNumbers = numbers.toSorted();
const reversedNumbers = numbers.toReversed();
```
この例では、`toSpliced()` を使用して配列をスプライスし、`toSort()` を使用して配列をソートし、`toReversed()` を使用して配列を逆順にします。これらは通常の `splice`、`sort`、および `reverse` と同様に機能しますが、違いは新しい配列を返し、元の配列を変更しない点です。
### findLast() and findLastIndex()
ES14以前では、配列内で特定の条件を満たす最後の要素またはインデックスを見つけたい場合、まず配列を逆順にする必要がありました。

```js
function findLastIndexByReversing(arr, target) {
  const reversedArray = arr.slice().reverse();
  const reversedIndex = reversedArray.indexOf(target);

  if (reversedIndex !== -1) {
    const lastIndex = arr.length - 1 - reversedIndex;
    return lastIndex;
  } else {
    return -1; 
  }
}
```
この例では、`findLastIndexByReversing` は `slice().reverse()` を使用して元の配列の逆転したコピーを作成します。その後、`indexOf` を使用して逆転した配列内で目標要素の最初の発生を見つけます。関数は元の配列の長さから逆転したインデックスを引いた値を計算します。これにより、元の配列内での要素の最後のインデックスが得られます。

また、末尾から始まる `for` ループを使用できます。例えば：
```js
function findLastIndex(arr, target) {
  for (let i = arr.length - 1; i >= 0; i--) {
    if (arr[i] === target) {
      return i;
    }
  }
  return -1;
}
```
この例では、`findLastIndex` 関数は配列` arr `と目標要素 `target` を取ります。それは配列を末尾から始まりの `arr.length - 1 `から` 0 `まで反復処理します。目標要素を見つけた場合、インデックスを返します。要素が見つからない場合は -1 を返します。

色々なやり方があるけど今では`lastIndexOf`と呼ばれるメソッドでやったら結構楽になると思います。
このメソッドを使えば配列の末尾から始まり、条件を満たす最初の要素の値を返します。
```js
const fruits = ['apple', 'banana', 'orange', 'banana', 'kiwi'];

const lastIndex = fruits.lastIndexOf('banana');
```
# まとめ
これがECMAScript 2023としてJavaSrciptに導入された変更点です。

もし記事の簡単なビデオバージョンをご覧になりたい場合は、[こちら](https://youtu.be/XSfJZyTKpdA)をご確認ください。
この[リンク](https://www.freecodecamp.org/news/the-biggest-changes-in-javascript-this-year/?ref=dailydev)を参考しました。

お読みいただきありがとうございます。
エアークローゼット [Advent Calendar 2023](https://qiita.com/advent-calendar/2023/air-closet)はまだ続きますので、ぜひ他のエンジニア, デザイナー, PMの記事もご覧いただければと思います。
よろしくお願いします！