【もりけん塾】JavaScript課題4 まとめ
webコーダーのsaco @sacocco_sacoya です。
所属しているもりけん塾にてマークアップエンジニアの方がフロントエンドエンジニアになる為の課題4に挑戦しました。
備忘録&勉強になったことをまとめていきます。
課題内容
[{to: "bookmark.html", img: "1.png", alt:"画像1", text: "ブックマーク"}, {to: "message.html", img: "2.png", alt:"画像2", text: "メッセージ"}]
という配列を使って以下のようなHTML出力にしてください
<ul>
<li><a href="/bookmark.html"><img src="1.png" alt="画像1">ブックマーク</a></li>
<li><a href="/message.html"><img src="2.png" alt="画像2">メッセージ</a></li>
</ul>
作成にあたって
前回の課題3でオブジェクトを利用して回答していたので、土台はできていました。
塾生のはるさんのこちらの記事で、「for of」や「forEach」で書く方法があること、今回の課題のようなケースでは「forEach」を利用すると良いと知り、これらを利用して、前回の土台からの書き直しに挑戦しました。
提出コード
const ul = document.getElementById("js-lists");
const fragment = document.createDocumentFragment();
const contents = [
{ to: "bookmark.html", img: "1.png", alt: "画像1", text: "ブックマーク" },
{ to: "message.html", img: "2.png", alt: "画像2", text: "メッセージ" },
];
contents.forEach ((content)=> {
const image = document.createElement('img');
const anchor = document.createElement('a');
const li = document.createElement('li');
image.src = content.img;
image.alt = content.alt;
anchor.href = "/" + content.to;
fragment.appendChild(li)
.appendChild(anchor)
.appendChild(image)
.insertAdjacentText('afterend',content.text);
})
ul.appendChild(fragment);
レビューにて勉強になったこと
var / let / constの使い分けについて
塾生のはせがわさんより、letをconstへ変更してくださいとコメントいただき、ver / let / constの使い分けが曖昧であることに気が付きました。
- var
再宣言・再代入が行われるため、予期せぬエラーが発生するので危険。現在は非推奨。ブロックスコープ非適用。 - let
再宣言不可能だが、再代入は可能。ループや条件分岐内での使用、値の再代入が必要な場合は利用。ブロックスコープが有効。 - const
再宣言・再代入不可能。基本的にはすべてconstでの記述が推奨されている。ブロックスコープが有効。
基本的にはconstでの宣言が安全であると学びました。
使い分けポイントも学ぶことができてよかったです。
テンプレートリテラルの使用
anchor.href = "/" + content.to;
//↓テンプレートリテラルに書き換え
anchor.href = `./${content.to}`;
hrefの記述を上記のように調整しました。
塾生のはせがわさんより、テンプレートリテラルでの記述をおすすめいただきました。
テンプレートリテラルで記述した方がパッと見たときわかりやすいように感じました。
文字列と変数を同時に利用したいときは、テンプレートリテラルで記述するようにしたいと思いました。
アロー関数の記述方法
contents.forEach ((content)=> {//..
}
contents.forEach (content => {//...
}
アロー関数において、引数が1つの場合は括弧を省略できると知りました。(塾生のはせがわさんより教えていただきました。)
複数の引数がある場合は括弧が必須のようです。
どちらの記法がよいかはプロジェクトの方針によって変わってくるとのことでした。
idにはJSを、classにはスタイルを
<ul id="js-lists" class="lists"></ul>
塾生のはるさんより教えていただきました。
コード提出時、idしか記述しておらず、idに対して画像サイズ調整のスタイルを当てていたのですが、js接頭辞にはJSを利用し、スタイルにはスタイル用のクラスでわけると良いと教えていただきました。
こういった細やかな点に気が付きながら構築していきたいと思いました。
プルリクエスト
プルリクエストの内容はこちら。
備忘録
以下、課題に取り組むにあたって調べたことの備忘録です。
forEach
配列名.forEach(function(引数){
//繰り返し処理を記述
});
前回の課題で、forEach文についてさらっとメモをしていましたが、今回の課題では実際にfor文からforEachメソッドに書き換えてみました。(for ループから forEach への変換がMDNに記載されていました。)
以下、forEachの特徴をおさらいします。
- 配列オブジェクトに対して定義されているメソッドのため、配列以外には利用できない。
- コードがシンプルで読みやすい
- for文と違い、途中でループを終了させることができない
- HTMLCollection(配列風オブジェクト)には利用できない
このような特徴があります。
使用方法は、配列名.forEach(function(引数){}として、コールバック関数に引数を指定することで、配列の中の要素が1つずつ取得できます。
今回の課題をforEachメソッドで記述した場合
const ul = document.getElementById("js-lists");
const fragment = document.createDocumentFragment();
const contents = [
{ to: "bookmark.html", img: "1.png", alt: "画像1", text: "ブックマーク" },
{ to: "message.html", img: "2.png", alt: "画像2", text: "メッセージ" },
];
contents.forEach ((content)=> {
let image = document.createElement('img');
let anchor = document.createElement('a');
let li = document.createElement('li');
image.src = content.img;
image.alt = content.alt;
anchor.href = "/" + content.to;
li.appendChild(anchor)
.appendChild(image)
.insertAdjacentText('afterend',content.text);
fragment.appendChild(li)
})
ul.appendChild(fragment);
for-of構文
for(変数 of 配列){
//繰り返し処理を記述
}
for of構文では、「配列」の値を1ずつ「変数」へ代入する、という記述となる。
for文で指定する初期値、条件式、増減値などの指定は不要であるため、使いたい配列名を指定して、それを取り出す変数名を指定するだけで利用できるのでシンプルで使いやすいというメリットがある。
for(const content of contents){
//繰り返し処理を記述
}
指定する変数には、(変数なので)let もしくは const を指定する必要がある。
for of文を利用する際の注意点
for of文は反復可能な(イテラブルな)オブジェクトには利用できるが、通常のオブジェクトには利用できない。
イテラブル・オブジェクトとは
配列、文字列などSymbol.iteratorプロパティを実装しているオブジェクトのこと。
var array = new Array();
console.log(array);
上記のように空の配列を作成し、コンソールで中身を確認するとSymbol.iteratorプロパティがみつかる。このプロパティが存在するものに対してはfor of文を利用できる。
通常のオブジェクトには、このプロパティが存在しないため利用することができない。
(通常のオブジェクトにはfor in文を使えばループを作成することができる。)
今回の課題をfor of文で記述した場合
const ul = document.getElementById("js-lists");
const fragment = document.createDocumentFragment();
const contents = [
{ to: "bookmark.html", img: "1.png", alt: "画像1", text: "ブックマーク" },
{ to: "message.html", img: "2.png", alt: "画像2", text: "メッセージ" },
];
for (const content of contents) {
let image = document.createElement('img');
let anchor = document.createElement('a');
let li = document.createElement('li');
image.src = content.img;
image.alt = content.alt;
anchor.href = "/" + content.to;
li.appendChild(anchor)
.appendChild(image)
.insertAdjacentText('afterend',content.text);
fragment.appendChild(li)
}
ul.appendChild(fragment);
forEachとfor ofの使い分け
forEachは記述が簡潔で、多くの場合に利用しやすいメソッドだが、for ofでしかできない処理もある。
- forEachは非同期処理には向いていない。(非同期として処理を記述しても、処理の完了を待たずに次のループに進む(処理が同期的である)ため)
- for of文は配列の要素を一つずつ処理するため、非同期処理に向いている。
これらのことから、非同期処理が必要な場合はfor of文を、それ以外のプレーンな配列処理に関してはforEachを利用するのが適切であるとわかりました。
今回の課題では非同期処理は不要であると判断し、forEach文での提出になりました。
感想
for文で作成していた課題をベースにfor of、forEachを使ってループ処理の書き換えを行いました。
それぞれの記述方法についてじっくり学ぶことで、for系のループ処理の記述に少し慣れることができたように思います。
頂いたレビューの中でも、今回も知らなかったことがたくさんあり、学びになりました。
貴重なお時間をいただき本当にありがとうございます。
レビューをしてくださったはせがわさん @starsurferz、また、レビューいただき、過去の課題記事も参考にさせていただいたはるさん @fuwafuwahappy、課題を作成してくださったもりけんさん @terrace_tech。ありがとうございました。
もりけん塾とは?
フロントエンドエンジニアを目指す方の無料コミュニティ「もりけん塾」。
「無料でJavaScript教え合うフロントエンドコミニュティ」です。
詳しくはこちら↓↓
https://kenjimorita.jp/morikenjuku
もりけん先生のTwitter↓↓
https://twitter.com/terrace_tech
参考記事・動画
【もりけん塾】JavaScript課題4で学んだことまとめ | <>haru log
【JavaScript入門】「for – of文」の使い方と間違いやすいポイントを徹底解説! | 侍エンジニアブログ
【JavaScript入門】forEach文の使い方と配列の繰り返し処理まとめ! | 侍エンジニアブログ
【JavaScript】var / let / const を本気で使い分けてみた #JavaScript – Qiita