1. JavaScriptの配列とは?
JavaScriptの配列(Array)は、複数の値を順序付きで格納できるデータ構造です。数値や文字列、オブジェクト、さらには別の配列までまとめて持つことができます。配列はインデックス(0から始まる連番)を使って各要素にアクセスします。
ITTI配列は「番号付きロッカー」をイメージするとわかりやすいでしょう。ロッカーの1つ1つに数値や文字列、オブジェクトなどを入れて管理できます。ただし、人間は「1番目」から数えますが、JavaScriptでは「0番目」から数える点に注意が必要です。
なぜfruistなのか
この記事では、JavaScriptの配列の基本を説明するために、fruitsという名前の配列を使っています。 たとえば、こんなコードです
const fruits = ["りんご", "バナナ", "オレンジ"];このfruitsという名前には、特別な意味や機能があるわけではありません。 単に「果物の名前を並べた配列」という、誰にとってもイメージしやすい例として使っているだけです。
実際の開発では、配列の中身に応じて、tasks(やることリスト)や users(ユーザー一覧)や products(商品リスト)など、より意味のある名前をつけるのが一般的です。
JavaScriptでは、変数名(この場合は fruits)は自由に決められます。大切なのは「その配列に何が入っているか」が分かるような名前をつけることです。
このように、fruitsはあくまで学習のための例。 コードの読みやすさや理解のしやすさを優先して選ばれている名前なんです。



ということで、ここからはコード専門官のイティセルが解説します。イティセルさん!よろしくお願いします!



イティセルです。読者の皆さんにわかりやすくお伝えしていきまーす
2. fruits配列の作成方法





配列リテラル([])内に要素をカンマで並べるだけです。後は、実行してみると…ぽちっ
const fruits = ['apple', 'orange', 'banana'];
console.log(fruits);


[‘apple’, ‘orange’, ‘banana’]
実行結果
['apple', 'orange', 'banana']


[] を囲まない状態で実行すると…ぽちっ
const fruits = 'apple', 'orange', 'banana'; ⇦ []を囲んでない
console.log(fruits);


SyntaxError: Unexpected string
実行結果
SyntaxError: Unexpected string → error


配列として認識されないので、JavaScriptはエラーを返します。



要素を()を囲んだ状態で実行すると…ぽちっ
const fruits = ('apple', 'orange', 'banana');
console.log(fruits);


banana
実行結果
'banana'


これは「カンマ演算子」と呼ばれる仕組みで、最後の要素だけが返されます。



カンマを使わずにそれぞれ宣言して実行すると…ぽちっ
const fruit1 = 'apple';
const fruit2 = 'orange';
const fruit3 = 'banana';
console.log(fruit1, fruit2, fruit3);


apple orange banana
実行結果
apple orange banana


配列ではなく、単に変数の値が並んで出力されます。いろいろな書き方がありますが、目的に合った方法を選ぶのが大切です。
3. 要素へのアクセスと基本操作


3.1 要素の取得



インデックスについて詳しく知りたい方は下のリンクを読んでみてくださいね。かなり網羅性があります。





(fruits[0])は[‘apple’, ‘orange’, ‘banana’]の中のappleを指定しています。実行してみると…ぽちっ
const fruits = ['apple', 'orange', 'banana'];
console.log(fruits[0]);


‘apple’
実行結果
'apple'


(fruits[1])はorangeを指定しています。実行してみると…ぽちっ
const fruits = ['apple', 'orange', 'banana'];
console.log(fruits[1]);


‘orange’
実行結果
'orange'


(fruits[2])はbananaを指定しています。実行してみると…ぽちっ
const fruits = ['apple', 'orange', 'banana'];
console.log(fruits[2]);


‘banana’
実行結果
'banana'


このように、fruits[インデックス]を使うことで、配列の中から特定の要素を取り出すことができます。
3.2 配列の長さ取得



`length` を使うと、配列に含まれる要素の数がわかります。 例えば [‘apple’, ‘orange’, ‘banana’] には 3 つの要素があります。
実行してみると…ぽちっ
const fruits = ['apple', 'orange', 'banana'];
console.log(fruits.length); 


3
実行結果
34. 要素の追加・削除


4.1 pushとpop



fruitsの配列に’grape’を追加したいときは、push()を使います。 fruits.push(‘grape’);と書いて、実行してみると…ぽちっ!
const fruits = ['apple', 'orange', 'banana'];
fruits.push('grape');
console.log(fruits);


[‘apple’, ‘orange’, ‘banana’, ‘grape’]
実行結果
['apple', 'orange', 'banana', 'grape']


ちゃんと末尾に追加されましたね。
ゲームで例えるなら、まるでゾンビが湧くように次々と出現する感じです。push()を使えば、ホラーゲームの敵出現ロジックにも応用できそうですね。



2つ方法があります。
1つ目は、単純に ‘grape’ を削除して配列を [‘apple’, ‘orange’, ‘banana’] にする方法です。
2つ目は、削除した要素を変数に保存して、本当に削除されたかどうかを確認する方法です。



1つ目の方法
[‘apple’, ‘orange’, ‘banana’, ‘grape’] の中で ‘grape’ を削除したいときは pop()を使います。
実行してみると…ぽちっ
const fruits = ['apple', 'orange', 'banana', 'grape'];
const last = fruits.pop();
console.log(fruits);


[‘apple’, ‘orange’, ‘banana’]
実行結果
['apple', 'orange', 'banana']


2つ目の方法
削除された要素を確認したいときは、pop()の戻り値を変数に代入します。
実行してみると…ぽちっ
const fruits = ['apple', 'orange', 'banana', 'grape'];
const last = fruits.pop();
console.log(last);


‘grape’
実行結果
'grape'


削除された’grape’が表示されましたね。
これでpop()が「末尾の要素を削除し、その値を返す」ことがわかります。
4.2 unshiftとshift



[‘apple’, ‘orange’, ‘banana’]の中で一番先に’strawberry’を追加したい。
そんな時はunshift()を使います。
fruits.unshift(‘strawberry’);を書いて実行してみると…ぽちっ
const fruits = ['apple', 'orange', 'banana'];
fruits.unshift('strawberry');
console.log(fruits);


[‘strawberry’, ‘apple’, ‘orange’, ‘banana’]
実行結果
['strawberry', 'apple', 'orange', 'banana']


先頭に’strawberry’が追加されましたね。
次は、先頭の’strawberry’を消したいのでshift()を使います。
const first = fruits.shift();を書いて実行してみると…ぽちっ
const fruits = ['strawberry', 'apple', 'orange', 'banana'];
const first = fruits.shift();
console.log(first);


‘strawberry’
実行結果
'strawberry'


あれれ、’strawberry’だけが表示されましたね。
これはshift()が「削除した要素」を返すからです。
では「本当に消えたのか?」を確認してみましょう。
console.log(fruits);を書いて実行してみると…ぽちっ
const fruits = ['strawberry', 'apple', 'orange', 'banana'];
const first = fruits.shift();
console.log(fruits); 


[‘apple’, ‘orange’, ‘banana’]
['apple', 'orange', 'banana']


確かに’strawberry’が消えています。
まとめると
first → 削除された要素
fruits → 削除後に残った配列
fruits と first の違いに注意してくださいね。
4.3 spliceによる任意位置操作



splice(1, 1, ‘melon’) の意味はこうなります。
1 → 開始位置(インデックス1 = ‘orange’ の場所)
1 → 削除する要素の数(1件 = ‘orange’ を削除)
‘melon’ → 代わりに挿入する要素
つまり「’orange’ を削除して、その場所に ‘melon’ を入れる」という動きです。
実際にコードを書いて実行してみましょう…ぽちっ
const fruits = ['apple', 'orange', 'banana'];
fruits.splice(1, 1, 'melon');
console.log(fruits);


[‘apple’, ‘melon’, ‘banana’]
実行結果
['apple', 'melon', 'banana']5. 配列の反復処理


5.1 forループ



まず `let i = 0` で変数 i を 0 からスタートさせます。
これはループ用のカウンタ変数です。
次に条件式 `i < fruits.length` を見てみましょう。
`fruits.length` は配列の要素数を表し、今回の配列 `[‘apple’, ‘orange’, ‘banana’]` では 3 になります。
`i < fruits.length`は「i が配列の長さより小さい間はループを続ける」という意味です。
つまり、実際の動きはこうなります。
1. i = 0 → 0 < 3 は true → fruits[0] = ‘apple’ を表示
2. i = 1 → 1 < 3 は true → ‘orange’ を表示
3. i = 2 → 2 < 3 は true → ‘banana’ を表示
4. i = 3 → 3 < 3 は false → ループ終了
では、コードを書いて実行してみましょう…ぽちっ
const fruits = ['apple', 'orange', 'banana'];
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}


apple
orange
banana
実行結果
apple
orange
banana5.2 for…ofループ



for (… of …) は、配列や文字列など「反復可能なオブジェクト」を順番に取り出す構文です。
要するに「配列の中身を順番に繰り返し処理する」仕組みです。
const fruit は、ループのたびに配列の要素が代入されます。
1回目は ‘apple’、2回目は ‘orange’、3回目は ‘banana’ …という具合です。
配列に入っているfruitの3つの要素を順番に取り出すには、console.log(fruit)を書いて実行してみると…ぽちっ
const fruits = ['apple', 'orange', 'banana'];
for (const fruit of fruits) {
console.log(fruit);
}


apple
orange
banana
実行結果
apple
orange
banana5.3 forEachメソッド



fruits.forEach(…) は、配列 fruits の要素を先頭から順番に処理します。
イメージとしては「forEach は箱の中身(fruits)を順番に取り出して確認する人」のようなものです。
(fruit, idx) => { … } の部分では、
fruit → 取り出した要素(’apple’, ‘orange’, ‘banana’)
idx → その要素のインデックス番号(0, 1, 2)
となります。
では、実際に console.log(`${idx}: ${fruit}`) を書いて実行してみると…ぽちっ
const fruits = ['apple', 'orange', 'banana'];
fruits.forEach((fruit, idx) => {
console.log(`${idx}: ${fruit}`);
});


0: apple
1: orange
2: banana
実行結果
0: apple
1: orange
2: banana6. 高度な組み込みメソッド


6.1 mapによる変換



fruits.map(…) は、配列 fruits の要素を順番に取り出して処理します。
ここでは f => f.toUpperCase() と書いているので、取り出した要素([‘apple’, ‘melon’, ‘banana’])f を大文字に変換します。
その結果を集めて、新しい配列として upperFruits に代入します。
大文字に変換されたかどうかを確認するには、console.log(upperFruits) を書いて実行してみると…ぽちっ
const fruits = ['apple', 'melon', 'banana'];
const upperFruits = fruits.map(f => f.toUpperCase());
console.log(upperFruits);


[‘APPLE’, ‘MELON’, ‘BANANA’]
実行結果
['APPLE', 'MELON', 'BANANA']6.2 filterによる絞り込み



fruits.filter(…) は、配列 fruits の要素を1つずつ取り出して、カッコの中の条件式でチェックします。
f => f.length > 5 は「取り出した要素 f の文字数が 5 より大きいかどうか」を判定します。
例えば:
‘apple’ → 長さ 5 → 条件に合わない
‘melon’ → 長さ 5 → 条件に合わない
‘banana’ → 長さ 6 → 条件に合う
結果は条件に合った ‘banana’ だけが新しい配列に残ります。
では、コードを書いて実行してみると…ぽちっ
const fruits = ['apple', 'melon', 'banana']
const longNames = fruits.filter(f => f.length > 5);
console.log(longNames);


[‘banana’]
実行結果
['banana']6.3 reduceによる集約



fruits.reduce(…) は、配列 fruits の要素を順番に受け取り、カッコの中の処理で累積していきます。
reduce((acc, f) => acc + ‘,’ + f, ”) は、わかりやすく言うと「要素を一つずつ取り出して、前の結果にカンマをつけてつなげる」処理です。
最初の処理では空文字に ‘apple’ が加わり、`,apple` になります。まるでベルトコンベアで部品を組み立てる工場のようですね。
結果を確認するには console.log(joined); を実行してみると…ぽちっ
const fruits = ['apple', 'melon', 'banana'];
const joined = fruits.reduce((acc, f) => acc + ',' + f, '');
console.log(joined);


,apple,melon,banana
実行結果
,apple,melon,banana6.4 findとfindIndex



find は「条件に合う最初の要素」を返します。
ここでは fruits.find(f => f.startsWith(‘m’)) と書いていますが、`startsWith(‘m’)` は「m で始まるかどうか」を判定する条件です。
そのため、最初にヒットする ‘melon’ が返ってきます。
では、結果を確認するためにconsole.log(found); を書いて実行してみると…ぽちっ
const fruits = ['apple', 'melon', 'banana'];
const found = fruits.find(f => f.startsWith('m'));
console.log(found);


melon
実行結果
melon


findIndex は「条件に合う最初の要素のインデックス番号」を返します。
fruits.findIndex(f => f === ‘banana’) をわかりやすく言うと、findIndex が「banana は何番目かな?」と調べてくれるイメージです。
‘banana’ は配列の3番目の要素ですが、JavaScript ではインデックスが 0 から始まるので番号は 2 になります。
では、結果を確認するために console.log(idx); を書いて実行してみると…ぽちっ
const fruits = ['apple', 'melon', 'banana'];
const idx = fruits.findIndex(f => f === 'banana');
console.log(idx);


2
実行結果
26.5 includesとindexOf



includes の役割は、配列に指定した要素が「含まれているかどうか」を調べることです。
返り値は true または false になります。
今回は、includes を使って fruits の中に ‘melon’ と ‘grape’ があるかどうかを確かめてみましょう。
console.log(fruits.includes(‘melon’));
console.log(fruits.includes(‘grape’));
両方を書いて実行してみると…ぽちっ
const fruits = ['apple', 'melon', 'banana'];
console.log(fruits.includes('melon''));
console.log(fruits.includes('grape'));


true
false
true →ある
false →ない


indexOf は、配列の中で指定した要素が「最初に現れる位置(インデックス)」を返します。
返り値はインデックス番号です。(見つからなければ -1 になります)
では、’banana’ は何番目か? ‘grape’ は何番目か? を確かめてみましょう。
console.log(fruits.indexOf(‘banana’));
console.log(fruits.indexOf(‘grape’));
両方を書いて実行してみると…ぽちっ
const fruits = ['apple', 'melon', 'banana'];
console.log(fruits.indexOf('banana'));
console.log(fruits.indexOf('grape'));


2
-1
2
-1


あれぇー?grapeは-1ってことはfruitsの配列には含まれていない証拠だね。
7. 配列のコピーと結合


7.1 spread構文



ここでは copy / more / combined の3パターンを紹介します。
copy はコピー
more はコピーに新しい要素を足す
combined は複数の配列を合体させる
more の場合、fruits に ‘kiwi’ を追加すると
[‘apple’, ‘melon’, ‘banana’, ‘kiwi’] になります。
配列と要素の合体です。
combined の場合、fruits と [‘pear’,’peach’] を合わせるので
[‘apple’, ‘melon’, ‘banana’, ‘pear’, ‘peach’] になります。
配列と配列の合体です。
では、コードを書いて実行してみると…ぽちっ
const fruits = ['apple', 'melon', 'banana'];
const copy = [...fruits];
const more = [...fruits, 'kiwi'];
const combined = [...fruits, ...['pear','peach']];


ブツ…ブツ…
copy → ['apple', 'melon', 'banana']
more → ['apple', 'melon', 'banana', 'kiwi']
combined → ['apple', 'melon', 'banana', 'pear', 'peach']7.2 concatメソッド



concat とは、「既存の配列をそのまま残したまま、新しい配列をくっつけて“連結した配列”を返す」メソッドです。
つまり、配列と配列の合体です。
fruits.concat([‘pear’,’peach’]); と書いてあるので、fruitsと[‘pear’,’peach’] を合わせます。
この結果を知りたいので、コードを書いて実行してみると…ぽちっ
const fruits = ['apple', 'melon', 'banana'];
const merged = fruits.concat(['pear','peach']);


[‘apple’, ‘melon’, ‘banana’, ‘pear’, ‘peach’]
['apple', 'melon', 'banana', 'pear', 'peach']8. 分割代入による参照





[firstFruit, secondFruit, …rest] と書くと、
firstFruit → ‘apple’
secondFruit → ‘melon’
…rest → 残りの要素をまとめた配列 → [‘banana’]
となります。
もし fruits の要素が4つなら、rest には [‘banana’, ‘kiwi’] のように2つ入ります。
では、結果を知るためのコードを書いて実行してみると…ぽちっ
const fruits = ['apple', 'melon', 'banana'];
const [firstFruit, secondFruit, ...rest] = fruits;
console.log(firstFruit);
console.log(rest);


‘apple’
‘melon’
[‘banana’]
'apple'
'melon'
['banana']9. その他の配列操作


9.1 sortとreverse



sort() はデフォルトでは「文字列として」昇順に並び替えます。
reverse() は配列の要素を逆順に並べます。
要するに、sort はアルファベット順(abc…)、reverse は逆アルファベット順(zyx…)というイメージです。
では、実行結果を知るためのコードを書いて実行してみると…ぽちっ
const fruits = ['apple', 'melon', 'banana'];
const sorted = [...fruits].sort();
const reversed = [...fruits].reverse();


[ ‘apple’, ‘banana’, ‘melon’ ]
[ ‘banana’, ‘melon’, ‘apple’ ]
[ 'apple', 'banana', 'melon' ]
[ 'banana', 'melon', 'apple' ]9.2 joinとtoString



join(‘ | ‘) は、配列の要素を ‘ | ‘ で区切って 1つの文字列にします。
要するに、apple と melon の間に | を入れて「apple | melon」にするイメージです。
toString() は、配列を文字列に変換しますが、区切り文字は常にカンマ , です。
つまり、apple と melon の間に , を入れて「apple,melon」にします。
では、実際にコードを実行して確認してみると…ぽちっ
const fruits = ['apple', 'melon', 'banana'];
console.log(fruits.join(' | '));
console.log(fruits.toString());


apple | melon | banana
apple,melon,banana
apple | melon | banana
apple,melon,banana10. 二次元配列の例





‘apple’ → 名前
120 → 価格
30 → 在庫数
という二次元配列です。例えば、バナナは価格60円、在庫100個という情報を加えることができます。
ただし、何が何の数字かは見ただけでは分かりにくいのが弱点です。
「バナナ 60 100」って並んでいても、なにそれ?って思いますよね。
const fruitInfo = [
['apple', 120, 30],
['orange', 80, 50],
['banana', 60, 100]
];


こちらは「名前付きのプロパティ」で管理できるので可読性が高いです。
例えば fruitObjects[0].price と書けば「apple の価格」をすぐに取り出せます。
プロパティ名があるので、何の値かが一目で分かり便利です。
少し冗長にはなりますが、ミスを減らしやすく、コードの保守や拡張もしやすくなります。
const fruitObjects = [
{ name: 'apple', price: 120, stock: 30 },
{ name: 'orange', price: 80, stock: 50 },
{ name: 'banana', price: 60, stock: 100 }
];11. イミュータブル操作のベストプラクティス





[…fruits]はfruitsの配列をコピーします。ただし、浅いコピーなので、ネストされた配列やオブジェクトの中身まではコピーされません。
const newArr = [...fruits];


Deep copyは深いコピーなのでネストされた配列やオブジェクトの中身もコピーできます。ただし、関数や undefined、Date などは正しくコピーできない制約がある。
const deep = JSON.parse(JSON.stringify(fruitObjects));


Immutable.js は「専用の永続データ構造」を提供するライブラリで、効率的にイミュータブル操作を行えるのが強みです。
Immer は「通常の JavaScript オブジェクトや配列」をそのまま使いながら、イミュータブル操作を簡単に書けるようにするライブラリです。



「イミュータブル操作って何それ?」と思うかもしれませんが、意味がわかると「あっー」となるはずです。
簡単にいうと、破壊的操作(元の配列を直接書き換えること)を避けて、元の配列はそのままに、新しい配列を作って扱うやり方です。
要するに「勝手に合体してしまう」ことを防ぐ仕組みです。新しい配列だけに要素を追加したいのに、元の配列まで勝手に追加してしまう…そんなことを避けられます。



Immutable.js は Facebook が開発したライブラリで、高速かつメモリ効率が良いのが特徴です。ただし独自の API を学ぶ必要があり、通常の JavaScript 配列やオブジェクトとは互換性が低めです。
Immer は JavaScript との相性が良く、普段通りの書き方でイミュータブル操作ができますが、大規模データではパフォーマンスが落ちる場合があります。
12. ES2022新機能:at() メソッド





最新の機能である at() を使うと、配列の中の要素をインデックスで簡単に取り出すことができます。
特に負のインデックスが使えるのがポイントです。
(fruits.at(-1)) は配列の最後の要素。
(fruits.at(0)) は配列の最初の要素。
(fruits.at(-2)) は配列の後ろから2番目の要素です。
では、本当にそうなるのかコードを書いて実行してみましょう…ぽちっ
const fruits = ['apple', 'melon', 'banana'];
console.log(fruits.at(-1));
console.log(fruits.at(0));
console.log(fruits.at(-2));


‘banana’
‘apple’
‘melon’
'banana'
'apple'
'melon'AIひろゆきの会話
コラム:実務でのインデックス活用を会話で学ぼう!



以上がfruits配列の説明でした。どう思いますか?



いや、配列を直接いじるのって、短期的には楽なんですけど、長期的に見るとバグの温床になるんですよ。優秀な人って、結局イミュータブル操作を徹底するんですよね。
なんでかっていうと、状態が勝手に合体したり壊れたりしないから、後からコードを読む人が混乱しないんです。
だから push とか pop をそのまま使うんじゃなくて、map とか filter とか、あるいは Immer を選ぶんです。
結局“優秀な人ほどイミュータブルを選ぶ”ってことなんですよ。



確か、イミュータブル操作って「元の配列を直接いじらずに、新しい配列を作ることで他に影響しないようにする」ためのコードだったよね。



そうですね。イミュータブル操作って、元の配列を直接いじらずに新しい配列を作ることで、他に影響しないようにするコードなんですよ。
結局、優秀な人ほどこういう書き方を選ぶんです。なんでかっていうと、後からコードを読む人が混乱しないし、バグも減るから。
だから push とかで直接いじるんじゃなくて、map とか filter とか、あるいは Immer を使う。
つまり“優秀な人はイミュータブルを選ぶ”ってことなんですよね。
13. まとめ


JavaScript の配列を最初から最後まで通して学んでみると、ただの「値を並べる箱」じゃなくて、実に多彩な表情を持った道具だとわかります。最初はロッカーのように単純に値を入れて取り出すだけですが、push や pop で増減させたり、for…of や forEach で自然に回したり、map や filter で新しい配列を生み出したりと、使い方次第でどんどん便利さが広がっていきます。
さらに、イミュータブル操作を意識することで「他の配列に勝手に影響してしまう」ような事故を防げるし、最新の at() メソッドを使えば末尾アクセスも直感的に書ける。つまり、配列は単なる基礎知識にとどまらず、コードの読みやすさや保守性、そしてチーム開発での信頼性に直結する重要なテーマなんです。
結局のところ、優秀な人ほど「元の配列を壊さない」書き方や「新しいメソッド」を自然に選んでいく。この記事を通して、配列の基礎から応用、そして最新仕様まで一気に押さえられたのは大きな収穫だと思います。
名言
あなたはやったことよりも、やらなかったことに失望する
この記事が参考になったと感じたら、ぜひシェアやコメントで教えてください。
今後の改善に役立てます。最後まで読んでいただき、ありがとうございました。









コメント