つくる 表示名を決める
このレッスンで分かること
- 第3章で学んだ演算子だけで、表示に使う値を決める関数が書けます
||で空欄を埋め、??で未設定を埋め、三項演算子で文言を切り替えますif文を使わなくても、値を決めるだけの処理は式で書き切れます
つくる 表示名を決める とは
第3章の総まとめです。ニックネーム、肩書き、作品数から、プロフィールの見出しに出す 4 つの値を演算子だけで決めます。
ここまでで何ができるようになったか
第3章では、値と値を組み合わせて別の値を作る道具を 5 つ手に入れました。
| レッスン | 手に入れた道具 | できるようになったこと |
|---|---|---|
比較演算子と === | === !== >= | 型まで含めて等しいかを判定する |
| 論理演算子と短絡評価 | && || ! | 条件を組み合わせ、値そのものを取り出す |
| 三項演算子 | ? : | 条件でふたつの値を選ぶ |
?? で既定値 | ?? | null と undefined のときだけ既定値にする |
| 演算子の優先順位 | () | 複雑な式を正しく読み、正しく書く |
この 5 つを合わせると、「入力がそろっていなくても壊れない表示用の値」を作れるようになります。プロフィールサイトで言えば、ニックネームを登録していない人、肩書きを空欄で保存した人、まだ作品が 1 件もない人、その全員に対して適切な見出しを出す、ということです。
実際のサービスでは、データが完璧にそろっていることのほうが珍しいです。空欄、未入力、まだ 0 件。この「そろっていない状態」をどう表示するかを決めるのが、フロントエンドの仕事の半分と言っても言い過ぎではありません。
つくるもの
buildHeader という関数を作ります。受け取るのは 4 つの値です。
| 引数 | 型 | 説明 |
|---|---|---|
nickname | 文字列 | ニックネーム。未登録なら空文字や null が来る |
fullName | 文字列 | 本名。山田 太郎 |
jobTitle | 文字列 | 肩書き。空欄で保存されることがある |
worksCount | 数値 | 作品の件数。未計測なら null や undefined |
返すのは、見出しに使う 4 つの値をまとめたオブジェクトです。
{
displayName: "たろう",
subtitle: "フロントエンド志望",
worksLabel: "作品 3 件",
worksCount: 3
}ルールは次のとおりです。
displayNameは、ニックネームがあればそれ、空欄なら本名、どちらもなければ名無しsubtitleは、肩書きがあればそれ、空欄ならWeb エンジニアを目指していますworksCountは、nullやundefinedなら0に倒した数値worksLabelは、件数が 1 以上なら作品 3 件の形、0なら作品はまだありません
どの演算子を当てるか
ルールをひとつずつ演算子に翻訳していきます。
空欄も未設定もまとめて埋めるところは ||
ニックネームは、未登録のときに空文字で保存されることもあれば null のこともあります。どちらの場合も本名に倒したいので、falsy すべてに反応する || が向いています。
const displayName = nickname || fullName || "名無し";|| は左から順に truthy な値を探し、見つかったらそれを返します。3 つ並べれば「ニックネーム、なければ本名、それもなければ名無し」という優先順位がそのまま式になります。肩書きも同じ考え方です。
0 を守りたいところは ??
作品件数は事情が違います。0 は「まだ作品がない」という意味のある値なので、|| で埋めてしまうと台無しです。ここは null と undefined にだけ反応する ?? を使います。
const count = worksCount ?? 0;これで、null が来ても undefined が来ても数値の 0 になり、実際に 0 件のときはそのまま 0 が残ります。同じ「既定値を入れる」処理でも、値の意味によって演算子を変える。これが第3章のいちばんの学びどころです。
文言の切り替えは三項演算子
件数が決まったら、表示する文字列を選びます。ふたつのうちどちらか、なので三項演算子の出番です。
const worksLabel = count > 0 ? "作品 " + count + " 件" : "作品はまだありません";条件は count > 0 です。count はすでに ?? で数値に倒してあるので、null や undefined が紛れ込む心配をせずに比較できます。前の処理で値の形をそろえておくと、後の処理の条件がシンプルになります。この積み重ねが、読みやすいコードの正体です。
if文をまだ学んでいないのに、これだけの判定が書けてしまいました。「処理を分ける」のがifの仕事、「値を選ぶ」のが演算子の仕事です。値を決めるだけなら、演算子のほうが短く読みやすく書けます。
組み立てる
4 つの値がそろったら、オブジェクトにまとめて返します。
function buildHeader(nickname, fullName, jobTitle, worksCount) {
const displayName = nickname || fullName || "名無し";
const subtitle = jobTitle || "Web エンジニアを目指しています";
const count = worksCount ?? 0;
const worksLabel = count > 0 ? "作品 " + count + " 件" : "作品はまだありません";
return { displayName, subtitle, worksLabel, worksCount: count };
}{ displayName, subtitle, worksLabel } のように変数名だけを書くと、同じ名前のキーに値が入ります。省略記法と呼ばれる書き方で、第7章で詳しく扱います。いまは { displayName: displayName } と同じ意味だと思ってください。
4 つの値をひとつずつ
constに置いてから返しているのは、名前が説明になるからです。ひとつの長い式に詰め込むこともできますが、途中の値に名前を付けたほうが、あとから読む人に親切です。
動きを確かめる
いろいろな入力を渡して、期待どおりの値が返るか確かめます。
console.log(buildHeader("たろう", "山田 太郎", "フロントエンド志望", 3));
// { displayName: "たろう", subtitle: "フロントエンド志望", worksLabel: "作品 3 件", worksCount: 3 }
console.log(buildHeader("", "山田 太郎", "", 0));
// { displayName: "山田 太郎", subtitle: "Web エンジニアを目指しています", worksLabel: "作品はまだありません", worksCount: 0 }
console.log(buildHeader());
// { displayName: "名無し", subtitle: "Web エンジニアを目指しています", worksLabel: "作品はまだありません", worksCount: 0 }3 つ目に注目してください。引数をひとつも渡していないのに、エラーにならず、表示に使える値がきちんと返っています。第2章で学んだ「渡されなかった引数は undefined になる」という性質と、|| と ?? の既定値が組み合わさった結果です。
こういう関数を「壊れにくい」と表現します。呼び出す側がどんな状態でも、画面に出せる値が必ず返る。プロフィールサイトを実際に動かすとき、この性質が効いてきます。第8章で DOM に値を差し込むようになると、ここで作った buildHeader の戻り値をそのまま画面に流し込めます。
よくある間違い
- 数値の既定値に
||を使う — 今回は既定値が0なのでworksCount || 0でもたまたま同じ結果になります。しかし既定値が0以外のとき、たとえばviews || 10と書くと、実際に0回だった閲覧数が10にすり替わります。数値には??、と決めておくと事故りません ??と||を括弧なしで混ぜる —nickname || fullName ?? "名無し"は SyntaxError です。別々のconstに分けるか、括弧を書いてください
// const displayName = nickname || fullName ?? "名無し"; // SyntaxError
const displayName = (nickname || fullName) ?? "名無し"; // 括弧を書けば動く- 数値と文字列の連結を忘れる —
"作品 " + count + " 件"の+は、左が文字列なので連結として働きます。順番を変えてcount + " 件"と書くと数値が文字列に変換されて連結されますが、count + 1 + " 件"のように算術を混ぜるときは、意図した順に計算されているか確かめてください
要件
- 関数名は
buildHeader、引数はnicknamefullNamejobTitleworksCountの 4 つにすること - 戻り値は
displayNamesubtitleworksLabelworksCountの 4 つのキーを持つオブジェクトにすること - 空文字の肩書きは既定値に置き換えるため
||を使い、件数は0を守るため??を使うこと if文を使わず、三項演算子で表示文を切り替えること
入出力例
buildHeader("たろう", "山田 太郎", "フロントエンド志望", 3) → {"displayName":"たろう","subtitle":"フロントエンド志望","worksCount":3,"worksLabel":"作品 3 件"}
buildHeader("", "山田 太郎", "", 0) → {"displayName":"山田 太郎","subtitle":"Web エンジニアを目指しています","worksCount":0,"worksLabel":"作品はまだありません"}
buildHeader(null, null, null, null) → {"displayName":"名無し","subtitle":"Web エンジニアを目指しています","worksCount":0,"worksLabel":"作品はまだありません"}
buildHeader() → {"displayName":"名無し","subtitle":"Web エンジニアを目指しています","worksCount":0,"worksLabel":"作品はまだありません"}
buildHeader("たろう", "山田 太郎", null, 1) → {"displayName":"たろう","subtitle":"Web エンジニアを目指しています","worksCount":1,"worksLabel":"作品 1 件"}