配列から一覧を描画する
このレッスンで分かること
- オブジェクトの配列から要素を量産する組み立て方
- 「1 件を要素に変える関数」を切り出す意味
forEachの中で条件に合わないものを飛ばす書き方
配列から一覧を描画する とは
作品データの配列を 1 件ずつまわし、それぞれに対応するカードをつくって並べる操作です。データを足せばカードが増える状態になります。
手で書いたコードは 1 枚ぶんしかない
前回、作品カードを 1 枚つくりました。ここで、もう 2 枚足したくなったとします。素直にやるなら、同じ 10 行をもう 2 回書くことになります。
const newCard2 = document.createElement("article");
newCard2.className = "work-card";
const newHeading2 = document.createElement("h3");
// … あと 7 行、名前だけ変えてもう一度変数名の末尾に番号が増えていくコードは、たいてい何かがおかしいという合図です。第5章で配列を学び、第6章で forEach を学び、第7章でオブジェクトの配列を扱ったのは、この場面のためでした。ここで 3 つが合流します。
やることは 2 つです。
- 作品の情報をオブジェクトの配列にまとめる
- 「1 件のオブジェクトからカードをつくる関数」を書き、配列を
forEachでまわして呼ぶ
これができると、作品を増やしたいときに書き足すのは配列の 1 行だけになります。DOM を組み立てるコードは 1 か所のまま増えません。
データを配列にする
第7章で決めた作品オブジェクトの形をそのまま使います。プロパティは 4 つです。
| プロパティ | 型 | 意味 |
|---|---|---|
title | 文字列 | 作品の名前 |
year | 数値 | つくった年 |
views | 数値 | 表示された回数 |
published | 真偽値 | 公開してよいか |
これから足す 3 件を配列にします。
const extraWorks = [
{ title: "JavaScript のメモ帳", year: 2026, views: 0, published: true },
{ title: "クリックできるボタン", year: 2026, views: 8, published: true },
{ title: "つくりかけの計算機", year: 2026, views: 3, published: false }
];3 件目の published が false になっています。まだ人に見せたくない作品です。この 1 件はカードにしません。データの側に「出すかどうか」を持たせておくと、表示のコードを直さずに公開と非公開を切り替えられます。
こうやってデータと表示を分けておく形を、データ駆動と呼びます。React や Vue のような道具は、この考え方を突きつめて自動化したものです。いまここで手で書いている流れが、そのまま土台になります。
1 件を要素に変える関数
forEach のコールバックの中に 10 行の組み立てを直接書いてもいいのですが、それでは中身が読みにくくなります。1 件ぶんの組み立てを関数に切り出し、要素を返させます。
function createWorkCard(work) {
const card = document.createElement("article");
card.className = "work-card";
const heading = document.createElement("h3");
heading.textContent = work.title;
const meta = document.createElement("p");
meta.className = "work-meta";
meta.textContent = work.year + " 年 / " + work.views + " 回表示";
card.append(heading, meta);
return card;
}前回書いた 10 行とほとんど同じです。違うのは 2 点だけで、固定の文字だったところが work.title や work.year になったことと、最後に return card で要素を返していることです。
関数が返せるのは数値や文字列だけではありません。要素も 1 つの値なので、そのまま返せます。第7章でオブジェクトを返す関数を書いたのと同じことです。
この関数には、DOM に足す処理を入れていません。「つくって返す」ところで止めておくと、どこに足すかを呼ぶ側が決められます。1 つの関数に 1 つの仕事だけをさせておくと、あとで使い回しが効きます。
配列をまわして並べる
あとは forEach でまわし、返ってきた要素を親に足すだけです。
const workList = document.querySelector(".work-list");
extraWorks.forEach((work) => {
if (!work.published) {
return;
}
workList.append(createWorkCard(work));
});if (!work.published) { return; } が、非公開の作品を飛ばす部分です。第6章で学んだ早期 return の形をそのまま使っています。ここでの return はコールバック 1 回ぶんを終えるという意味で、forEach 全体が止まるわけではありません。次の要素の処理はふつうに続きます。
for ループの continue と同じはたらきだと考えると分かりやすくなります。forEach の中では break も continue も書けないので、飛ばしたいときはこの return を使います。
forEachを途中で完全に止めたい場面では、for-ofに書き換えてbreakを使います。一覧を描くときは全部まわすのがふつうなので、この章ではforEachだけで足ります。
今回書きかえるもの
前回書いた「4 枚目を手で組み立てる 11 番のブロック」は、もう役目を終えます。あの部分をまるごと消して、今回のデータ配列と関数と forEach に置きかえてください。手で 1 枚つくるコードと、配列から量産するコードが両方あると、同じカードが二重に出てしまいます。
置きかえたあとの画面では、作品ギャラリーが 5 枚になります。内訳は HTML に書いてある 3 枚と、配列から描かれた 2 枚です。published が false の「つくりかけの計算機」は出てきません。
ここまで来ると、次のことが実感できるはずです。配列の中に 1 行足せば、カードが 1 枚増える。published を false にすれば、カードが 1 枚消える。DOM を組み立てるコードには一切さわらずに、画面が変わります。これがデータから画面をつくるということです。
よくある間違い
関数の中で return を忘れる
createWorkCard の最後の return card を書き忘れると、関数は undefined を返します。append(undefined) は文字列の "undefined" を足してしまうので、カードのかわりにその文字だけが並びます。
function createWorkCard(work) {
const card = document.createElement("article");
// … 組み立て
// return card; を忘れると undefined が返る
}createElement を forEach の外に置く
要素は 1 件ごとに新しくつくらないといけません。外で 1 つだけつくって使いまわすと、同じ要素が親から親へ移動するだけで、最後の 1 枚しか残りません。
const card = document.createElement("article"); // 外に置いてはいけない
extraWorks.forEach((work) => {
card.textContent = work.title;
workList.append(card); // 毎回同じ要素が移動するだけ
});forEach の中で return すれば全部止まると思う
止まりません。飛ばすだけです。1 件でも条件に合うものが見つかったら終わりにしたい、という処理は forEach には向いていません。第7章の find を使うか、for-of に書き換えます。
課題
extraWorksに 3 件のオブジェクトを入れる。中身は「JavaScript のメモ帳 / 2026 / 0 / true」「クリックできるボタン / 2026 / 8 / true」「つくりかけの計算機 / 2026 / 3 / false」createWorkCard(work)を書く。article.work-cardの中にh3とp.work-metaを入れ、つくった要素をreturnするp.work-metaの文字は"2026 年 / 8 回表示"の形にする。work.yearとwork.viewsから組み立てるextraWorksをforEachでまわし、publishedがfalseのものはreturnで飛ばして.work-listに足す