つくる 表示名を決める

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部

このレッスンで分かること

  • 第3章で学んだ演算子だけで、表示に使う値を決める関数が書けます
  • || で空欄を埋め、?? で未設定を埋め、三項演算子で文言を切り替えます
  • if 文を使わなくても、値を決めるだけの処理は式で書き切れます

つくる 表示名を決める とは

第3章の総まとめです。ニックネーム、肩書き、作品数から、プロフィールの見出しに出す 4 つの値を演算子だけで決めます。

ここまでで何ができるようになったか

第3章では、値と値を組み合わせて別の値を作る道具を 5 つ手に入れました。

レッスン手に入れた道具できるようになったこと
比較演算子と ====== !== >=型まで含めて等しいかを判定する
論理演算子と短絡評価&& || !条件を組み合わせ、値そのものを取り出す
三項演算子? :条件でふたつの値を選ぶ
?? で既定値??nullundefined のときだけ既定値にする
演算子の優先順位()複雑な式を正しく読み、正しく書く

この 5 つを合わせると、「入力がそろっていなくても壊れない表示用の値」を作れるようになります。プロフィールサイトで言えば、ニックネームを登録していない人、肩書きを空欄で保存した人、まだ作品が 1 件もない人、その全員に対して適切な見出しを出す、ということです。

実際のサービスでは、データが完璧にそろっていることのほうが珍しいです。空欄、未入力、まだ 0 件。この「そろっていない状態」をどう表示するかを決めるのが、フロントエンドの仕事の半分と言っても言い過ぎではありません。

つくるもの

buildHeader という関数を作ります。受け取るのは 4 つの値です。

引数説明
nickname文字列ニックネーム。未登録なら空文字や null が来る
fullName文字列本名。山田 太郎
jobTitle文字列肩書き。空欄で保存されることがある
worksCount数値作品の件数。未計測なら nullundefined

返すのは、見出しに使う 4 つの値をまとめたオブジェクトです。

{ displayName: "たろう", subtitle: "フロントエンド志望", worksLabel: "作品 3 件", worksCount: 3 }

ルールは次のとおりです。

  • displayName は、ニックネームがあればそれ、空欄なら本名、どちらもなければ 名無し
  • subtitle は、肩書きがあればそれ、空欄なら Web エンジニアを目指しています
  • worksCount は、nullundefined なら 0 に倒した数値
  • worksLabel は、件数が 1 以上なら 作品 3 件 の形、0 なら 作品はまだありません

どの演算子を当てるか

ルールをひとつずつ演算子に翻訳していきます。

空欄も未設定もまとめて埋めるところは ||

ニックネームは、未登録のときに空文字で保存されることもあれば null のこともあります。どちらの場合も本名に倒したいので、falsy すべてに反応する || が向いています。

const displayName = nickname || fullName || "名無し";

|| は左から順に truthy な値を探し、見つかったらそれを返します。3 つ並べれば「ニックネーム、なければ本名、それもなければ名無し」という優先順位がそのまま式になります。肩書きも同じ考え方です。

0 を守りたいところは ??

作品件数は事情が違います。0 は「まだ作品がない」という意味のある値なので、|| で埋めてしまうと台無しです。ここは nullundefined にだけ反応する ?? を使います。

const count = worksCount ?? 0;

これで、null が来ても undefined が来ても数値の 0 になり、実際に 0 件のときはそのまま 0 が残ります。同じ「既定値を入れる」処理でも、値の意味によって演算子を変える。これが第3章のいちばんの学びどころです。

文言の切り替えは三項演算子

件数が決まったら、表示する文字列を選びます。ふたつのうちどちらか、なので三項演算子の出番です。

const worksLabel = count > 0 ? "作品 " + count + " 件" : "作品はまだありません";

条件は count > 0 です。count はすでに ?? で数値に倒してあるので、nullundefined が紛れ込む心配をせずに比較できます。前の処理で値の形をそろえておくと、後の処理の条件がシンプルになります。この積み重ねが、読みやすいコードの正体です。

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 + " 件" のように算術を混ぜるときは、意図した順に計算されているか確かめてください

要件

  1. 関数名は buildHeader、引数は nickname fullName jobTitle worksCount の 4 つにすること
  2. 戻り値は displayName subtitle worksLabel worksCount の 4 つのキーを持つオブジェクトにすること
  3. 空文字の肩書きは既定値に置き換えるため || を使い、件数は 0 を守るため ?? を使うこと
  4. 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 件"}

ヒント

main.js
main.js
学習モード

メモ

つくる 表示名を決める

⌘S で保存