JavaScript基礎文法:処理を組み立てるの導入スライド
JavaScript基礎文法:処理を組み立てる - if / else if / else で段階判定
経験年数からレベルを決める
プロフィールに出す「入門」「初級」「中級」「上級」は、経験年数から決めています。こういう範囲で区切る判定は、if のうしろに else if を並べて書くのが定石です。else if は「上の条件に当たらなかったときだけ見る条件」という意味です。
当たった時点で残りは見ません。この「最初の 1 本だけ」を、次の図解で自分で動かして確かめます。
years が 3 なので、上から 3 番目の years < 7 で初めて当たります。
const years = 3;
if (years < 1) {
console.log("入門");
} else if (years < 3) {
console.log("初級");
} else if (years < 7) {
console.log("中級");
} else {
console.log("上級");
}
// 中級1 / 4
JavaScript基礎文法:処理を組み立てる - if / else if / else で段階判定
上から順にどの枝を通るか追う
経験年数のつもりで x のスライダーを動かし、太くなる線を上から順に目で追ってください。
- 太い線は必ず 1 本だけ。上のひし形で当たると、下のひし形にはそもそも線が届かない
- x を 0 から 9 の間で動かしても、通る道は変わらず結果も同じまま
- 「else を消す」を入れて x を 10 以上にすると、どこにも当たらず何も表示されなくなる
2 / 4
考えてみよう外しても進めます
さきほどのコードで、条件の並びだけを years < 7、years < 3、years < 1 の順に入れ替えました。years が 0 のとき、何が表示されるでしょうか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 4
JavaScript基礎文法:処理を組み立てる - if / else if / else で段階判定
範囲で区切るときの書きかた
else if は上から順に見るので、下の条件では「上に当たらなかった」ことが済んだ前提になります。おかげで下限を書かなくて済み、式がそのぶん短くなります。
狭い条件から先に、広い条件をあとに並べる。これだけ守れば、段階の判定はほぼ書けます。
| 出したいレベル | 書く条件 |
|---|---|
| 1 年未満 | if (years < 1) |
| 1 年以上 3 年未満 | else if (years < 3) |
| 3 年以上 7 年未満 | else if (years < 7) |
| 7 年以上 | else |
| 上の下限を書きたくなったら | 上から順に見ているので不要 |
4 / 4
JavaScript基礎文法:処理を組み立てる - FizzBuzz で複数条件を組み立てる
倍数かどうかは余りで見る
数を 3 で割った余りが 0 なら、その数は 3 の倍数です。JavaScript では % という記号で割り算の余りが出せます。この余りが 0 かどうかだけで、倍数の判定ができます。
3 の倍数でも 5 の倍数でもある 15 を、どちらに振り分けるのか。それを決めるのが条件を書く順番です。
15 は 3 でも 5 でも余りが 0 になります。ここが今回の山場です。
console.log(15 % 3); // 0
console.log(15 % 5); // 0
console.log(7 % 3); // 11 / 4
きつい条件を一番上に置く
3 の倍数なら Fizz、5 の倍数なら Buzz、両方に当てはまる 15 の倍数なら FizzBuzz と出します。15 の判定を一番上に置くと、15 は Fizz に取られる前に FizzBuzz で拾えます。
n % 15 === 0一番きつい条件n % 3 === 015 を素通りさせないconsole.log(n)どれにも当たらない数n を 1 から 15 まで変えたとき
| n の値 | 表示されるもの |
|---|---|
| 1 | 1 |
| 2 | 2 |
| 3 | Fizz |
| 4 | 4 |
| 5 | Buzz |
| 6 | Fizz |
| 7 | 7 |
| 8 | 8 |
| 9 | Fizz |
| 10 | Buzz |
| 11 | 11 |
| 12 | Fizz |
| 13 | 13 |
| 14 | 14 |
| 15 | FizzBuzz |
1 から 14 までは 3 と 5 のどちらか一方にしか当たりません。両方に当たるのは 15 だけです。
この表で見るべき行は最後の 1 行だけです。ここが Fizz になっていたら、条件の順番を間違えています。
2 / 4
考えてみよう外しても進めます
同じコードで、n % 15 === 0 の判定だけを一番下 (else の直前) に移しました。n が 15 のとき、何が表示されるでしょうか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 4
条件を並べる順番の決めかた
当てはまる数が少ない条件ほど上に置きます。逆にすると、広い条件が先に拾ってしまい、下の条件が一度も使われないコードになります。
n % 15 === 0
一番上。当てはまるのは 15 の倍数だけ
n % 3 === 0
2 番目。15 の倍数は上で拾い終わっている
n % 5 === 0
3 番目。残っているのは 5 の倍数だけ
どれにも当たらない
else。数をそのまま出す
n % 3 === 0 && n % 5 === 0 は n % 15 === 0 と同じ意味です。作品数や公開状態でプロフィールの表示を変えるときも同じです。狭い条件から順に並べる、と覚えておいてください。
4 / 4
JavaScript基礎文法:処理を組み立てる - 配列のきほん
作品名をひとつの入れ物にまとめる
作品が 3 つあるからといって、変数を 3 つ用意する必要はありません。配列という入れ物を使うと、いくつもの値を 1 つの変数にまとめて置いておけます。角かっこの中にカンマで並べるだけで作れます。
取り出すときの番号は 1 からではありません。その数え方を次の枚で確かめます。
角かっこの中の番号が、何番目の値を取り出すかの指定になります。
const works = ["名刺サイト", "ミニ電卓", "todoリスト"];
console.log(works[0]); // 名刺サイト
console.log(works.length); // 31 / 4
番号は 0 から数える
先頭の値の番号は 0 です。作品が 3 つなら使える番号は 0 と 1 と 2 までで、3 番はどこにもありません。無い番号を読んでも JavaScript は止まらず、undefined という「何も入っていない」を表す値を返します。
works[2]最後の値works[3]入れ物が無い場所取り出した結果
| 書き方 | 返ってくる値 |
|---|---|
| works[0] | 名刺サイト |
| works[1] | ミニ電卓 |
| works[2] | todoリスト |
| works[3] | undefined |
囲った行だけ、値ではなく undefined が返っています。
エラーで止まらないぶん、番号を 1 つずらしたまま先へ進んでしまいます。ここが配列でいちばん多い間違いです。
2 / 4
考えてみよう外しても進めます
works に作品名が 3 つ入っているとき、works[3] を console.log すると何が出るでしょうか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 4
JavaScript基礎文法:処理を組み立てる - 配列のきほん
配列でよく使う書き方
配列に対してやりたいことは、だいたいこの 6 つに収まります。今は意味だけ分かれば十分で、書き方は必要になったときに見返してください。
最後の値の番号が length から 1 引いた数になるのは、番号が 0 から始まるからです。次のレッスンで、この 1 の差がそのまま落とし穴になります。
| やりたいこと | 書き方 |
|---|---|
| 作る | const works = ["名刺サイト"] |
| 何番目かを取り出す | works[0] |
| いくつ入っているか | works.length |
| 最後の値を取り出す | works[works.length - 1] |
| 末尾に 1 つ足す | works.push("ブログ") |
| 中身を全部見る | console.log(works) |
4 / 4
JavaScript基礎文法:処理を組み立てる - for ループで合計を求める
同じ処理を配列の数だけくり返す
作品ごとの制作日数を足し合わせたいとき、works[0] から順に手で書いていくと配列が増えるたびに書き直しになります。for 文を使うと、配列の長さに合わせて自動でくり返してくれます。
3 つの式のうち、真ん中の条件を 1 文字変えるだけで結果が壊れます。次の枚で見てください。
丸かっこの中はセミコロンで 3 つに分かれていて、それぞれ役割が違います。
const days = [3, 5, 2];
let total = 0;
for (let i = 0; i < days.length; i++) {
total += days[i];
}
console.log(total); // 101 / 4
条件を 1 文字変えると 1 周多く回る
配列の長さは 3 ですが、使える番号は 0 と 1 と 2 までです。条件を i <= days.length と書くと i が 3 のときも回ってしまい、存在しない days[3] を足すことになります。
i <= days.length1 周多く回ってしまうtotal += days[i]足していく所1 周ごとの中身
| i | days[i] | total |
|---|---|---|
| 0 | 3 | 3 |
| 1 | 5 | 8 |
| 2 | 2 | 10 |
| 3 | undefined | NaN |
囲った 4 周目で undefined を足したせいで、それまでの 10 まで NaN になります。
NaN は「数として表せない」という値です。合計が 1 つ足りないのではなく、答えそのものが数でなくなります。
2 / 4
考えてみよう外しても進めます
days に数字が 3 つ入っているとき、for (let i = 0; i < days.length; i++) の中身は何周動くでしょうか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 4
JavaScript基礎文法:処理を組み立てる - for ループで合計を求める
for の 3 つの式が何をしているか
丸かっこの中は、書く場所ごとに役割が決まっています。この対応さえ頭に入れば、あとは中身を書くだけです。
配列を最後まで回すときの条件は必ず < です。<= と書きたくなったら、番号が 0 から始まることを思い出してください。
| 書く場所 | そこに書くこと |
|---|---|
| 1 つめ (初期化) | let i = 0 で数える変数を用意する |
| 2 つめ (条件) | i < days.length のうちはくり返す |
| 3 つめ (更新) | i++ で 1 周ごとに 1 増やす |
| 波かっこの中 | 毎周やりたい処理を書く |
| 合計をためる変数 | ループの外で let total = 0 |
4 / 4
JavaScript基礎文法:処理を組み立てる - while で条件を満たす間くり返す
回数ではなく条件でくり返す
for は「配列の数だけ」のように回数が決まっているときに使います。while は回数を決めず、条件が成り立っている間だけくり返します。残りの作品数が 0 になるまで、のような書き方に向いています。
for と違って、数える変数を増やしたり減らしたりする行は自分で書きます。この 1 行を落とすと何が起きるかを次の枚で見てください。
丸かっこの中の条件が真である間、波かっこの中がくり返し動きます。
let rest = 3;
while (rest > 0) {
console.log("残り " + rest + " 件");
rest = rest - 1;
}
console.log("全部できた");
// 残り 3 件
// 残り 2 件
// 残り 1 件
// 全部できた1 / 4
更新の行が無いと止まらなくなる
rest を減らす行を消しても、書き方としては正しいのでエラーは出ません。ただ rest がずっと 3 のままなので、条件 rest > 0 がいつまでも真になり、ブラウザが固まります。
let rest = 3ここから動かないrest > 0ずっと真のままrest の値を追う
| 周 | 更新あり | 更新なし |
|---|---|---|
| 1 周目 | 3 | 3 |
| 2 周目 | 2 | 3 |
| 3 周目 | 1 | 3 |
| 4 周目 | 0 になって止まる | 3 のまま止まらない |
右の列は 1 度も減らないので、条件が偽になる瞬間が来ません。
ループを止めるのは回数ではなく、条件を偽にする 1 行です。while を書いたら、まずその行がどこにあるかを探してください。
2 / 4
考えてみよう外しても進めます
let rest = 0; と書いたあとに while (rest > 0) を実行すると、波かっこの中は何周動くでしょうか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 4
JavaScript基礎文法:処理を組み立てる - while で条件を満たす間くり返す
for と while の使い分け
どちらもくり返しですが、向いている場面が違います。回数が先に分かっているかどうかで選ぶと、ほとんど迷いません。
while を書くときは、条件に出てくる変数が中身のどこかで変わっているかを必ず確かめます。変わらなければ、そのループは終わりません。
| やりたいこと | 向いている書き方 |
|---|---|
| 配列を先頭から最後まで見る | for |
| 5 回だけ動かす | for |
| 残りが 0 になるまで減らす | while |
| 正しい入力が来るまで待つ | while |
| 数える変数を増やす場所 | for は 3 つめの式、while は中身 |
4 / 4
JavaScript基礎文法:処理を組み立てる - break と continue でループを制御する
この周だけ飛ばす continue
作品名の配列に、まだ名前を決めていない空の要素が混ざることがあります。continue を書くと、その周の残りの処理をやめて次の周へ進みます。ループそのものは続くので、後ろの作品はちゃんと表示されます。
似た働きに break がありますが、こちらはループごと終わらせます。2 つを並べて次の枚で見比べます。
空の作品名だけが表示から抜け、残りはそのまま出てきます。
const works = ["名刺サイト", "", "ミニ電卓"];
for (let i = 0; i < works.length; i++) {
if (works[i] === "") {
continue;
}
console.log(works[i]);
}
// 名刺サイト
// ミニ電卓1 / 4
飛ばす周と、抜ける周
continue に当たった周は、その周の残りだけを飛ばして次に進みます。break に当たった周は、そこでループ全体が終わるので、後ろの要素は一度も見に行きません。
continueこの周だけ飛ばすbreakループごと抜ける1 周ごとの行き先
| i | works[i] | どうなるか |
|---|---|---|
| 0 | 名刺サイト | 表示する |
| 1 | 空の文字列 | continue で飛ばす |
| 2 | ミニ電卓 | 表示する |
| 3 | 非公開 | break でループを抜ける |
| 4 | todoリスト | ここまで来ない |
囲った 3 の行で終わるので、その先の 4 は一度も動きません。表示されるのは 2 件だけです。
取り消し線の 2 行は理由が違います。1 は飛ばされただけ、4 はもうループが終わっていて到達しません。
2 / 4
考えてみよう外しても進めます
上のコードの break を continue に書き換えると、console.log で表示されるのはどれになるでしょうか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 4
JavaScript基礎文法:処理を組み立てる - break と continue でループを制御する
どちらを使うか迷ったら
判断の基準は 1 つだけです。この先も配列を見続けたいなら continue、もう見なくてよいなら break を選びます。
if を付けずに単体で書くと 1 周目で必ず効いてしまいます。どちらも「ある条件のときだけ」とセットで使う道具です。
| やりたいこと | 書き方 |
|---|---|
| 条件に合わない要素を飛ばす | continue |
| 探していた 1 件が見つかったら終わる | break |
| 飛ばしたあとも残りを見る | continue |
| 抜けたあとは残りを見ない | break |
| どちらも書く場所 | if の中に書く |
4 / 4
JavaScript基礎文法:処理を組み立てる - デフォルト引数
引数を渡さなかったときの値を決めておく
プロフィールの肩書きは、まだ決めていない人もいます。呼ぶ側が肩書きを渡さなくても表示が崩れないように、関数の側であらかじめ使う値を決めておけます。これをデフォルト引数と呼び、引数名のうしろに = で書きます。
省いたときと渡したときで何が入るのかを、次の図解で呼び出しを増やしながら見ます。図解は Python の書き方ですが、既定値の仕組みは同じです。
title を省いた 1 行目だけ、= のうしろに書いた「学習中」が使われています。
function greet(name, title = "学習中") {
return name + "(" + title + ")";
}
console.log(greet("田中")); // "田中(学習中)"
console.log(greet("田中", "フロントエンド志望")); // "田中(フロントエンド志望)"1 / 4
JavaScript基礎文法:処理を組み立てる - デフォルト引数
省いた引数に何が入るか見る
「呼び出した回数」のスライダーを 0 から 3 まで動かしてください。
- 1 行目と 3 行目は引数を 1 つしか渡していないのに、戻り値にちゃんと ! が付いている
- 2 行目だけは ? を渡しているので、そちらが勝って ! は使われない
- 「既定値を [] にしてみる」のトグルは Python だけで起きる話なので、入れずに進めて大丈夫です
2 / 4
考えてみよう外しても進めます
肩書きの入力欄を空のまま送信すると、title には空文字 "" が渡ります。greet("田中", "") の結果はどれでしょうか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 4
既定値が使われるのは undefined のときだけ
何を渡しても既定値が出るわけではありません。既定値に切り替わるのは、引数が渡されなかったとき、つまり値が undefined のときだけです。null や空文字はそのまま素通りします。
greet("田中", undefined)ここまでが既定値の出番greet("田中", null)渡された値として扱われる戻り値
| 渡した 2 つめの引数 | title に入る値 | 戻り値 |
|---|---|---|
| 渡していない | 学習中 | 田中(学習中) |
| undefined | 学習中 | 田中(学習中) |
| null | null | 田中(null) |
| 空文字 | 空文字 | 田中() |
囲った 2 行だけが既定値に切り替わっています。下の 2 行は渡した値がそのまま入ります。
未入力を既定値で埋めたいときは、呼ぶ側が undefined を渡すか、そもそも引数を書かないようにします。
4 / 4
JavaScript基礎文法:処理を組み立てる - 早期 return でネストを浅くする
if を入れ子にすると右へ右へ伸びていく
作品の表示名を作る関数を、値が無い場合まで含めて書いてみます。「値があるか」を確かめてから中身を組み立てる、と素直に書くと if の中に if が入り、本来やりたい 1 行が一番奥に沈みます。
やっていることは変わらないまま、この形を平たく書き直せます。次の枚で書き換えた形と結果を並べます。
一番やりたい組み立ての行が、3 段目の奥に入り込んでしまっています。
function formatWork(work) {
if (work) {
if (work.title) {
return work.title + "(" + work.year + ")";
} else {
return "無題の作品";
}
} else {
return "作品がありません";
}
}1 / 4
先に弾いてから本体を書く
扱えない入力を冒頭で return して打ち切ってしまえば、そこから下は「値がそろっている場合」だけを考えれば済みます。else が消えて、本体が一番浅いインデントに戻ります。
if (!work) return "作品がありません";扱えない入力を先に返すreturn work.title本体は一番浅い所に戻る呼び出しの結果
| 渡した値 | 戻り値 |
|---|---|
| undefined | 作品がありません |
| { title: "", year: 2025 } | 無題の作品 |
| { title: "家計簿アプリ", year: 2025 } | 家計簿アプリ(2025) |
戻り値は入れ子で書いたときと 3 行とも同じです。変わったのは読みやすさだけです。
冒頭で打ち切るこの書き方をガード節と呼びます。関数の入口に「この場合は扱いません」と貼り紙をする形です。
2 / 4
考えてみよう外しても進めます
2 つのガード節の順番を入れ替えて !work.title の判定を先に書いたとき、formatWork(undefined) を呼ぶとどうなるでしょうか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 4
JavaScript基礎文法:処理を組み立てる - 早期 return でネストを浅くする
何をガード節にするか
冒頭で弾く対象は、だいたい決まった形をしています。「本体の計算が意味を持たない入力」を上から順に並べていきます。
上から順に弾いていくと、最後に残るのは「全部そろった場合」だけです。関数の本体はその 1 通りだけを書けば済みます。
| 弾きたい入力 | 冒頭に置く 1 行 |
|---|---|
| 値そのものが無い | if (!work) return "作品がありません"; |
| 必要な項目が空 | if (!work.title) return "無題の作品"; |
| 配列が 1 件も無い | if (works.length === 0) return "まだ作品がありません"; |
| 数値として扱えない | if (Number.isNaN(count)) return 0; |
| 権限が無い | if (!user.canEdit) return null; |
4 / 4
JavaScript基礎文法:処理を組み立てる - 変数のスコープ
関数の中で作った変数は外から見えない
変数には、その名前が通じる範囲があります。これをスコープと呼びます。関数の中で let や const を使って作った変数は、その関数の中だけで通じる名前になり、関数の外からは見えません。
見えるのはどの向きなのかを、次の図解で 4 通り全部試します。図解は Python の書き方でエラー名も NameError と出ますが、見え方の仕組みは JavaScript とまったく同じです。
最後の行だけが落ちます。mark は buildGreeting の中だけの名前だからです。
function buildGreeting(name) {
const mark = "さん";
return "こんにちは、" + name + mark;
}
console.log(buildGreeting("田中")); // "こんにちは、田中さん"
console.log(mark); // ReferenceError 外からは mark という名前が見えない1 / 4
JavaScript基礎文法:処理を組み立てる - 変数のスコープ
内と外のどちらから見えるか試す
「変数を置く場所」と「参照する場所」のボタンを 4 通りとも押してください。
- そとに置いてうちで参照すると値が出る。関数の中から外の変数は見える
- うちに置いてそとで参照したときだけ、うちの枠が曇って名前が見つからなくなる
- 4 通りのうち塞がるのはこの 1 通りだけ。見え方は片側通行になっている
2 / 4
考えてみよう外しても進めます
buildGreeting の中で作った mark を、関数の外の console.log で読もうとするとどうなるでしょうか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 4
中で宣言すれば外を汚さない
外側と同じ名前を関数の中で宣言しても、外の変数は書き換わりません。中で作った名前は中だけのものなので、関数をいくつ増やしても外の値は無事です。
const siteName = "作品一覧";中だけの新しい名前console.log(siteName)外の値はそのまま読んだ結果
| 読む場所 | siteName の値 |
|---|---|
| buildHeader の中 | 作品一覧 |
| 関数の外 | 田中のポートフォリオ |
囲った行は関数を呼んだあとに読んでいますが、外の値は最初のままです。
作業用の変数は関数の中で宣言する、と決めておくと、あとから関数を足しても他の場所が壊れません。
4 / 4
JavaScript基礎文法:処理を組み立てる - コールバック関数
関数を引数として渡す
関数は呼ぶだけのものではなく、値と同じように引数として渡せます。渡された側は、都合のよいときにその関数を呼びます。こうして渡す関数をコールバック関数と呼びます。
この括弧の有無が、コールバックで一番つまずく所です。付けた場合と付けない場合を次の枚で並べます。
最後の行で渡しているのは showTitle という名前だけで、括弧は付けていません。
const works = [{ title: "家計簿アプリ" }, { title: "天気ダッシュボード" }];
function showTitle(work) {
console.log(work.title);
}
function eachWork(list, action) {
for (const work of list) {
action(work);
}
}
eachWork(works, showTitle);
// "家計簿アプリ"
// "天気ダッシュボード"1 / 4
渡すのは関数そのもの
名前だけを書くと関数そのものが渡り、eachWork の中で作品の件数だけ呼ばれます。名前のうしろに括弧を付けると、渡す前にその場で 1 回呼ばれてしまい、渡るのは呼んだ結果のほうです。
showTitle)関数そのものが渡るshowTitle())先に呼ばれて結果が渡る実行したときの違い
| 書き方 | action に入るもの | 起きること |
|---|---|---|
| eachWork(works, showTitle) | showTitle という関数 | タイトルが 2 行出る |
| eachWork(works, showTitle()) | showTitle を呼んだ結果 | 渡す前にエラーで止まる |
下の行は eachWork にたどり着く前に落ちます。work を渡さないまま showTitle が呼ばれ、無いものの title を読もうとするからです。
括弧は「今ここで呼べ」という合図です。あとで呼んでほしいときは、括弧を付けずに名前だけを渡します。
2 / 4
考えてみよう外しても進めます
eachWork(works, showTitle()) と書いたとき、eachWork の action に入るのは何でしょうか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 4
JavaScript基礎文法:処理を組み立てる - コールバック関数
あとで呼んでもらう形はどこにでも出てくる
コールバックは特別な書き方ではなく、JavaScript のあちこちで同じ形が使われています。渡すのは関数そのもの、という所はどれも共通です。
一番下の書き方は第 9 章でブラウザを動かすときに使います。押される前に関数を預けておき、押された瞬間にブラウザが呼んでくれる、という同じ仕組みです。
| やりたいこと | 渡し方 |
|---|---|
| 1 件ずつ同じ処理をする | works.forEach(showTitle) |
| 条件に合うものだけ残す | works.filter(isPublished) |
| 1 件ずつ別の形に変える | works.map(toLabel) |
| 少し待ってから 1 回だけ実行する | setTimeout(showMessage, 1000) |
| ボタンが押されたら実行する | button.addEventListener("click", onClick) |
4 / 4
JavaScript基礎文法:処理を組み立てる - オブジェクトのきほん
関連する値を1つの箱にまとめる
作品1件を表すのに、タイトル用の変数、公開年用の変数、と別々に用意すると、どれとどれが同じ作品のものなのか分からなくなります。オブジェクトは、名前を付けた値をいくつでも1つの箱にまとめて持てる入れ物です。
値を取り出すときは、箱の名前のうしろに点とプロパティ名を書きます。
名前と値の組を並べて書きます。この名前のほうをプロパティと呼びます。
const work = {
title: "ポートフォリオサイト",
year: 2024,
views: 1200,
};
console.log(work.title); // ポートフォリオサイト1 / 4
読み方は2通り、書き足しは後からでもできる
取り出し方には点でつなぐ書き方と、角かっこに名前を文字で渡す書き方があります。まだ無いプロパティに値を入れると、その場で追加されます。
title: "ポートフォリオサイト"名前と値の組work.views = 1200後から足したプロパティ書いた式と返ってくる値
| 書いた式 | 返ってくる値 |
|---|---|
| work.title | "ポートフォリオサイト" |
| work["year"] | 2024 |
| work.views | 1200 |
| work.tags | undefined |
角かっこの書き方は、名前を文字として渡します。work[year] と引用符を外すと別の意味になります。
囲った行が、まだ入れていない tags を読んだときです。エラーにはならず undefined が返ります。
2 / 4
考えてみよう外しても進めます
tags を一度も入れていない work に対して、work.tags と書くとどうなりますか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 4
JavaScript基礎文法:処理を組み立てる - オブジェクトのきほん
オブジェクトの操作早見
このレッスンで出てくる書き方をまとめます。どれも作品オブジェクトをそのまま使って試せます。
点でつなぐ書き方は名前が決まっているときに使い、角かっこは名前が変数から来るときに使います。迷ったら点のほうで書けば足ります。
| やりたいこと | 書き方 |
|---|---|
| 決まった名前で読む | work.title |
| 変数に入った名前で読む | work[key] |
| 空白や記号を含む名前で読む | work["公開日"] |
| 値を書き換える | work.views = 1500 |
| 新しいプロパティを足す | work.published = true |
| 名前があるか調べる | "tags" in work |
4 / 4
JavaScript基礎文法:処理を組み立てる - const と参照
const が止めているのは入れ直しだけ
const で作った変数は変えられない、と読むと、中身も固まっていそうに見えます。実際に const が禁止しているのは、その名前に別のものを入れ直すことだけです。オブジェクトや配列の中身は書き換えられます。
変わらないのは「work がどの箱を指しているか」で、その箱の中身ではありません。
中身を直す3行目は通り、名前ごと入れ替える最後の行で止まります。
const work = { title: "ポートフォリオサイト", views: 1200 };
work.views = 1500;
console.log(work.views); // 1500
work = { title: "別の作品" }; // TypeError で止まる1 / 4
JavaScript基礎文法:処理を組み立てる - const と参照
代入で渡っているのは箱ではなく矢印
図解は Python の書き方ですが仕組みは同じです。コピーの切り替えで、箱がいくつ作られるか見てください。
- b = a と書いても箱は増えない。同じ箱を指す矢印が2本になるだけ
- だから a のほうを変えると b の中身も変わる。コピーしたつもりが同じものだった、が起きる
- コピーを入れると箱が2つに分かれ、片方を変えてももう片方は元のまま
2 / 4
考えてみよう外しても進めます
const a = { views: 100 }; const b = a; と書いてから b.views = 500; とした後、a.views は何になりますか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 4
通るもの、止まるもの
const とオブジェクトの組み合わせで、どこまでが守られてどこからが守られないのかを並べます。作品オブジェクトを work、作品の配列を works とします。
work = {} と入れ直す
TypeError。const が止めるのはここだけ
work.views = 1500
通る。中身は const の管轄外
works.push("新作")
通る。配列も同じ
const b = work
同じ箱を b からも指すだけ
const b = { ...work }
中身を写した別の箱ができる
b.tags を書き換える
写したのは1段目だけなので tags は共有のまま
最後の行が引っかかりやすい所です。中身を写す書き方でも、写されるのは1段目だけで、その中の配列やオブジェクトは元と同じ箱を指したまま残ります。
4 / 4
JavaScript基礎文法:処理を組み立てる - ?. で安全に取り出す
オブジェクトの中にオブジェクトが入る
作品の情報が増えてくると、作者や公開先のように、値そのものがまた1つのオブジェクトになります。中の値を取り出すときは、点を続けてたどっていきます。
困るのは、作者を登録していない作品が1件でも混ざったときです。
点をつないだぶんだけ、箱の中へ入っていきます。
const work = {
title: "ポートフォリオサイト",
author: { name: "山田", url: "https://example.com" },
};
console.log(work.author.name); // 山田1 / 4
途中が無いとその場で止まる
author が入っていない作品で work.author.name と書くと、undefined から name を取り出そうとして TypeError になります。点の前に ?. を足しておくと、途中が無い時点で undefined を返して先に進まなくなります。
work.author.name?. なしwork.author?.name?. あり書いた式と結果
| 書いた式 | 結果 |
|---|---|
| work.title | "ポートフォリオサイト" |
| work.author | undefined |
| work.author.name | TypeError で止まる |
| work.author?.name | undefined |
| work.author?.name ?? "名無し" | "名無し" |
取り消し線の行だけがプログラムを止めます。他はすべて値が返ります。
?. は「ここは無いかもしれない」と分かっている場所に付けます。無いときの代わりの値まで決めたいなら ?? を続けます。
2 / 4
考えてみよう外しても進めます
const work = { author: {} }; のとき、work.author?.name.length はどうなりますか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 4
JavaScript基礎文法:処理を組み立てる - ?. で安全に取り出す
?. の書き方早見
点だけでなく、角かっこや関数呼び出しの前にも同じ形で置けます。作品オブジェクトを work、作品の配列を works とします。
全部の点に ?. を付けたくなりますが、それをすると本当は必ずあるはずの場所で綴りを間違えても、静かに undefined が返るだけになります。付けるのは無いことが起こりうる場所だけです。
| やりたいこと | 書き方 |
|---|---|
| 途中が無いかもしれない | work.author?.name |
| 配列そのものが無いかもしれない | works?.[0] |
| 関数があるときだけ呼ぶ | work.render?.() |
| 無いときの代わりの値 | work.author?.name ?? "名無し" |
| あるか無いかだけ知りたい | work.author !== undefined |
4 / 4
JavaScript基礎文法:処理を組み立てる - 分割代入
必要な値をまとめて変数に取り出す
work.title、work.year と毎回書いていると、同じ work が何度も出てきて読みにくくなります。分割代入は、取り出したいプロパティの名前を左辺に並べて、同じ名前の変数を一度に作る書き方です。
並べなかった views は取り出されません。必要なものだけ書けば十分です。
左辺の中かっこは、新しいオブジェクトを作っているのではなく、取り出す名前を並べているだけです。
const work = { title: "ポートフォリオサイト", year: 2024, views: 1200 };
const { title, year } = work;
console.log(title, year); // ポートフォリオサイト 20241 / 4
名前の付け替えと、無いときの既定値
同じ名前の変数が既にあるときは別名を付けられます。プロパティが無いかもしれないときは、既定値を書いておくとその値で埋まります。
title: name別名で取り出すviews = 100既定値できあがる変数
| 変数 | 入る値 |
|---|---|
| name | "ポートフォリオサイト" |
| views | 0 |
| tags | [] |
title という変数は作られません。別名を付けた時点で、変数の名前は name のほうになります。
囲った行が引っかかる所です。views には 0 が入っているので既定値の 100 は使われません。既定値が効くのは値が undefined のときだけです。
2 / 4
考えてみよう外しても進めます
const { views = 100 } = { views: null }; と書いたとき、views には何が入りますか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 4
JavaScript基礎文法:処理を組み立てる - 分割代入
分割代入の書き方早見
配列にも同じことができます。作品オブジェクトを work、作品の配列を works とします。
オブジェクトは名前で取り出し、配列は前からの順番で取り出します。最後の行のように引数でそのまま受けると、関数の中で work. を書かずに済みます。
| やりたいこと | 書き方 |
|---|---|
| 名前を指定して取り出す | const { title, year } = work |
| 別の変数名にする | const { title: name } = work |
| 無いときの既定値 | const { views = 0 } = work |
| 配列から順に取り出す | const [first, second] = works |
| 残りをまとめて受ける | const { title, ...rest } = work |
| 引数で受け取る | function show({ title, year }) {} |
4 / 4
