8-1. 演習問題
問題1:選択問題
Section titled “問題1:選択問題”1-1. 次のコードを実行した結果として正しいものはどれか。
const x = 5;x = 10;- A.
xに 10 が代入される - B. 実行時エラーが発生する
- C.
xは 5 のままで、エラーは発生しない - D.
xにundefinedが代入される
解答と解説
正解:B
const で宣言した変数への再代入は実行時エラー(TypeError: Assignment to constant variable)になる。
- A:
constは再代入できないため誤り。 - C:エラーなしに無視されることはない。
- D:
undefinedが入ることはない。
const は「この変数は変わらない」という保証をプログラム全体に対して行う。コードの読み手がその変数を追いかける必要がなくなり、バグを防ぎやすくなる。
1-2. typeof null の結果はどれか。
- A.
"null" - B.
"undefined" - C.
"object" - D.
"boolean"
解答と解説
正解:C
typeof null === "object" はJavaScriptの有名なバグで、初期実装から引き継がれた歴史的な誤りだ。実際には null はオブジェクトではなくプリミティブ型なので、値が null かどうかを調べるには === null で厳密比較する。
const v = null;typeof v === "object" // true(でも null はオブジェクトではない)v === null // true(これが正しい null チェック)1-3. 次のコードの実行結果はどれか。
console.log("5" - 3);console.log("5" + 3);- A.
2と8 - B.
"5-3"と"53" - C.
2と"53" - D.
NaNと"53"
解答と解説
正解:C
JavaScriptの暗黙の型変換のルールを理解する問題だ。
-演算子は数値演算のみに使われるため、"5"が5に変換されて5 - 3 = 2+演算子は文字列連結にも使われるため、3が"3"に変換されて"5" + "3" = "53"
この非対称な振る舞いがバグの温床になる。文字列を数値に変換したいときは Number("5") または parseInt("5") を明示的に使う習慣をつけよう。
1-4. 次のコードの result の値はどれか。
const value = 0;const result = value ?? "デフォルト";- A.
"デフォルト" - B.
0 - C.
null - D.
undefined
解答と解説
正解:B
??(Null合体演算子)は左辺が null または undefined のときだけ右辺を返す。0 は null でも undefined でもないため、そのまま 0 が返る。
|| との違いが重要:
0 ?? "デフォルト" // 0 (0はnullでないのでそのまま)0 || "デフォルト" // "デフォルト"(0はfalsyなので右辺が返る)数値の 0 や空文字 "" を有効な値として扱いたい場合は ?? を使う。
問題2:穴埋め問題
Section titled “問題2:穴埋め問題”2. 次のコードの( )に入る適切なキーワードや値を答えよ。
// (1) 再代入不可の変数宣言(1) PI = 3.14159;
// (2) 文字列 "42" を数値に変換するconst num = (2)("42");
// (3) null か undefined のときだけデフォルト値を返す演算子const name = userInput (3) "名無し";
// (4) プロパティが存在しない場合でもエラーにならないアクセスconst city = user(4)address(4)city;解答と解説
constNumber(またはparseInt)???.(2か所とも)
解説
(1) const は宣言と同時に初期化が必要で、その後の再代入は不可。定数やイミュータブルな参照に使う。
(2) Number("42") は 42(数値)を返す。parseInt("42") も同じく 42 を返すが、parseInt("42px") → 42 のように文字列の先頭から数値を読む違いがある。
(3) ??(Null合体演算子)は null/undefined のときだけデフォルト値を返す。|| は 0 や "" もデフォルト値に置き換えてしまうため注意。
(4) ?.(オプショナルチェーン)は左辺が null または undefined なら undefined を返し、プロパティアクセスエラーを防ぐ。
問題3:記述問題
Section titled “問題3:記述問題”3-1. == と === の違いを説明し、なぜ常に === を使うべきなのかを述べよ。
解答と解説
==(抽象等値比較):型が異なる場合、型を変換してから値を比較する。変換ルールが複雑で直感に反する結果になりやすい。
0 == "" // true0 == false // true"1" == 1 // truenull == undefined // true===(厳密等値比較):型も値も両方が一致する場合にのみ true を返す。型変換を行わないため、結果が予測しやすい。
0 === "" // false0 === false // false"1" === 1 // falsenull === undefined // falseなぜ === を使うべきか:
== の型変換ルールを完全に記憶している開発者は少なく、意図せず true になったり false になったりするバグが発生しやすい。=== を使えばコードの意図が明確になり、レビューやデバッグの際も混乱が減る。唯一の例外として null チェックに == null を使う流派もあるが(null と undefined を同時にチェックできるため)、チームのコーディング規約に従うことが重要だ。
3-2. 次のコードはどのような問題を抱えているか説明し、修正案を示せ。
function getPrice(product) { return product.price * 1.1;}解答と解説
問題点:product が null や undefined の場合、product.price へのアクセスで TypeError: Cannot read properties of null が発生する。
修正案(いくつかのアプローチ):
// 1. オプショナルチェーンで安全にアクセスfunction getPrice(product) { return (product?.price ?? 0) * 1.1;}
// 2. ガード節で早期リターンfunction getPrice(product) { if (!product) return 0; return product.price * 1.1;}
// 3. デフォルト引数を活用function getPrice(product = { price: 0 }) { return product.price * 1.1;}実務では「関数の入口でnullチェックをして早期リターンする」パターンが読みやすくバグも少ない。
また product.price 自体も undefined の可能性があるため、product.price ?? 0 のように安全なデフォルト値を設定しておくとより堅牢になる。
問題4:ハンズオン
Section titled “問題4:ハンズオン”以下のプレイグラウンドでコードを実行し、結果を確認せよ。コードは自由に書き換えて試してよい。