【JavaScript】[]（配列）って何？

# 配列とは
個数が1以上あるデータや**個数がわからないデータ**は、配列で管理できます。
配列とは何か**連続したデータ**のこと、くらいの認識で大丈夫です。

<!-- また、配列でまとめて管理することで、それぞれのデータを具体的に知る必要がなくなります。 -->

## 作成方法
配列は値を`[]`で囲み、値同士を`,`で区切ると作成できます。

```js
[要素1, 要素2, etc...]
```

例えば、知っている果物の英単語をできるだけたくさん書いてみます。
このとき、以下のように配列を作成して書くことができます。

```js
const fluits = ['apple', 'orange', 'grape', 'kiwi']
```

ここでは4つ挙げてみました。

## インデックス
配列の要素はインデックスを使うことで取り出せます。
インデックスとは各要素に振られている番号で、**その要素が何番目にあるか**を示します。

この番号は`0`から始まります。
一番最初の要素が`0`、その次の要素が`1`、さらにその次の要素が`2`...という感じです。

```js
['apple', 'orange', 'grape', 'kiwi']
// appleのインデックスは0
// orangeのインデックスは1
// grapeのインデックスは2
// ...と続いていく
```

### ブラケット記法
特定のインデックスの要素を取得するには、ブラケット記法が使えます。
ブラケット記法は`配列名[インデックス]`という構文になっています。

```js
const fluits = ['apple', 'orange', 'grape', 'kiwi']

fluits[0] // apple
fluits[1] // orange
// ...と続いていく
```

## メソッド

作成した配列は`Array`という[オブジェクト型](https://tcd-theme.com/2021/05/javascript-data-object.html)になっています。

`Array`オブジェクト=配列には**たくさんのメソッド**が用意されており、追加の準備なしで便利な機能を使うことができます。

メソッドは配列の後に`.メソッド名()`で呼び出せます。
どんなメソッドがあるのかは[後](#基本的なメソッド)で紹介しますが、ここでは`push`メソッドを使ってみます。

```js
const fluits = ['apple', 'orange', 'grape', 'kiwi']

// メソッドを呼び出す
fluits.push('remon')

console.log(fluits) 
// ['apple', 'orange', 'grape', 'kiwi', 'remon']
```

`push`メソッドは、配列の最後に要素を追加するためのメソッドです。
ここでは配列の最後に`'remon'`が追加されています。

# 基本的なメソッド
ここからは配列でよく使うと思うメソッドを紹介します。

## forEach
`forEach`を使うと配列の要素を**順番に使う**ことができます。
つまり、配列の要素でループします。

このメソッドは引数に**関数**を取ります。

引数に入れた関数は各ループで**どんな処理をするか**を決めるもので、`forEach`メソッドの呼び出しとともに自動で呼び出されます。

```js
const array = ['要素1', '要素2']
array.forEach(elem => {
  console.log(elem)
})

// 出力:
// 要素1
// 要素2
```

例えば先ほど定義した`fluits`配列があります。
この内容から`fluits 0: apple`、`fluits 1: orange`のように、0から始まる番号と果物の英単語を一緒に出力する処理がこちらです。

```js
const fluits = ['apple', 'orange', 'grape', 'kiwi']

// fluitsにはフルーツが、indexには要素のインデックスが入る
fluits.forEach((fluits, index) => { 
  console.log(`fluits ${index}: ${fluits}`)
})

// fluits 0: apple
// fluits 1: orange
// fluits 2: grape
// fluits 3: kiwi
```

なお、配列の値でループする方法には`forof`文もあります。
詳しくは[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for...of)や[侍エンジニア](https://www.sejuku.net/blog/20228)をご覧ください。
<!-- 詳しくは[こちらの記事](for文の記事が公開されたらリンク貼る)で解説しているので、よければ併せてご覧ください。 -->

## includes

配列に**特定の要素が含まれれているか**調べられます。

`includes`は引数に含まれているか調べたい要素を取ります。
戻り値は真偽値で、含まれていたら`true`、含まれていなかったら`false`が返ってきます。

```js
const fluits = ['apple', 'orange', 'grape', 'kiwi']

fluits.includes('apple') // true
fluits.includes('orange') // true
fluits.includes('banana') // false
```

## push
配列の最後に値を追加します。
先ほど紹介したやつです。

`push`は引数に追加したい要素を取ります。
戻り値は追加したあとの配列の長さですが、あまり使う機会はないかもしれません。

```js
const fluits = ['apple', 'orange', 'grape', 'kiwi']

fluits.push('remon')
fluits.push('banana')

console.log(fluits) 
// ['apple', 'orange', 'grape', 'kiwi', 'remon']
```

## indexOf
ブラケット記法の逆で、**要素のインデックス**を取得できます。

`indexOf`は引数に調べたい要素を取ります。
ここに入れた要素と配列の要素が同じかどうかは、`===`を使ったときのように判定されます。

戻り値はその要素のインデックスです。
要素が見つからなかったら`-1`になります。

```js
const fluits = ['apple', 'orange', 'grape', 'kiwi']

fluits.indexOf('orange') // 1
fluits.indexOf('apple') // 0
fluits.indexOf('果物じゃない文字列') // -1
```

なお、同じ要素が複数入っている場合は、最初にある要素のインデックスが返されます。
最後の要素のインデックスが必要な場合は代わりに`lastIndefOf`メソッドが使えます。

詳細は[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)をご覧ください。

# 特徴
ここからはJavaScriptの配列の特徴について話します。

## 使える長さはほぼ無限
配列の要素に入れられる長さは**ほぼ無限**と言ってもいいと思います。

少なくとも、[C言語のような制約](https://9cguide.appspot.com/13-01.html)はありません。
メモリの解放などはJavaScriptランタイムがいい感じにやってくれます。

[この記事](https://qiita.com/mod_poppo/items/f3fcbc673526c84b9387#配列の長さ)の計測結果によると、こんな感じになるようです。

> |V8 (Node.js)|JavaScriptCore (osascript)|
> |:--|:--|
> |100663296 (0x6000000)|greater than 268435456|

> JSCの上限はよくわかりませんでした。十分な時間をかければわかるのかもしれませんが、人間の寿命は有限なので……。

## 可変
JavaScriptの配列は可変（ミュータブル）です。
そのため、**後から変更できます。**

変更には先ほど紹介した[`push`メソッド](#push)や[ブラケット記法](#ブラケット記法)が使えます。

```js
const fluits = ['apple', 'orange', 'grape', 'kiwi']

// インデックスが0の要素を変更する
fluits[0] = 'banana'

// 配列の最後に要素を追加する
fluits.push('remon')

console.log(fluits)
// ['banana', 'orange', 'grape', 'kiwi', 'remon']
// 初期化したときと変わってる
```

変更するためのメソッドを呼び出しているから当たり前だと思うかもしれませんが、JavaScriptじゃない言語だとたまにこうならないものもあります。