本セクションでは、データを動的に処理するための「JavaScriptの基本ロジック」を学びます。
&&, ||), Null合成演算子(??)map, filter, find)プログラムは一本道ではありません。「もし在庫があれば」「もしエラーなら」といった分岐が必要です。
const score = 85;
// 条件式が true の場合のみ実行される
if (score >= 80) {
console.log("合格!おめでとう");
} else {
// 条件式が false の場合
console.log("不合格...再挑戦しよう");
}
論理演算子 (&&, ||) は、単なる true/false 判定以上のことができます。
&&) (1/2)「左から順に見て、結果が決まった瞬間に止まる」 性質のことです。
false の場合: 右側を見ることなく、即座に終了します(結果は false)。これを ショートサーキット(短絡) と呼びます。true の場合: 「右側も見ないと結果が決まらない」ため、右側まで進みます。そして、右側の値をそのまま結果として返します。&&) (2/2)const isLoggedIn = true;
const userName = "Shake";
// isLoggedIn が true なので、右側の "Shake" が結果になる
const result = isLoggedIn && userName;
console.log(result); // "Shake"
「条件を満たす時だけ実行する(満たさない時は何もしない)」場合に便利です。
const debugMode = true;
// debugModeがONの時だけログを出す
debugMode && console.log("現在はデバッグモードです");
if (debugMode) { ... } と書くよりも短く、意図が明確になります。
||)|| は「左側が Falsy(無効な値) なら、右側の予備を使う」という動きをします。 これを利用して「デフォルト(初期値)」を設定することがよくあります。
// inputName が未入力("")や未定義(undefined)なら "ゲスト" にする
const inputName = "";
const displayName = inputName || "ゲスト";
console.log(displayName); // "ゲスト" (空文字は無効扱いになる)
||) の思わぬ落とし穴|| は 0 や ""(空文字)も「無効」と判定してしまうため、数値の0 を扱うアプリ(点数や在庫など)ではバグの原因になります。
// 「0点」という立派な記録なのに...
const score = 0;
// 0 は Falsy なので、予備の値(10)が採用されてしまう!
const displayScore = score || 10;
console.log(displayScore); // 10 (0点のはずなのに上書きされた)
??)この問題を解決するために登場したのが ?? です。 「完全に無 (null か undefined)」の時だけ 右側の予備を採用します。
const score = 0;
// 0 は「無」ではないので、そのまま採用される!
const displayScore = score ?? 10;
console.log(displayScore); // 0 (正しい!)
モダンな開発では、予期せぬバグを防ぐために基本的に ?? を推奨します。
どちらも「予備の値を設定する」役割ですが、「0 や 空文字 を有効な値として認めるか?」 が最大の違いです。
演算子 | 右側(予備)を採用する条件 | 特徴 |
| Falsy (0, "", null, undefined) |
|
| Nullish (null, undefined) |
|
関数とは 「複数の処理(手順)をひとつにまとめて、名前をつける」 仕組みです。 例えば「お風呂に入る」という行動を考えてみましょう。
これを、「お風呂に入る」 という一言にまとめるためのものが、「関数」 です。
const fillBath = () => console.log("1. お湯を入れます");
const undress = () => console.log("2. 服を脱ぎます");
const washBody = () => console.log("3. 体を洗います");
const soakInTub = () => console.log("4. 湯船に浸かります");
const getOutOfBath = () => console.log("5. お風呂から上がります");
const dryBody = () => console.log("6. 体を拭きます");
// 「お風呂に入る」という処理の塊(関数)を作る
function takeABath() {
fillBath(); // 1. お湯を入れる
undress(); // 2. 服を脱ぐ
washBody(); // 3. 体を洗う
soakInTub(); // 4. 湯船に浸かる
getOutOfBath(); // 5. 上がる
dryBody(); // 6. 体を拭く
}
// 次からは「お風呂に入る」と一言書くだけで、全部実行される!
takeABath();
いつもお風呂に入る時にわざわざ手順を全て説明しないように、複数の処理をまとめて一言で呼べるようにしたのが、「関数」 という概念です。
もう一つの重要な役割が 「入力(引数)を受け取り、出力(戻り値)を返す」 ことです。

「自動販売機」 をイメージすると分かりやすいです。
// お金(money)を受け取って、結果(戻り値)を返す関数
function buyDrink(money) {
if (money >= 150) {
return "コーラ"; // 外に結果を返す
} else {
return "お金が足りませんでした";
}
}
const myDrink = buyDrink(200); // 200円を入れる
console.log(myDrink); // "コーラ"
JavaScriptの関数は、時代とともに書き方が進化してきました。 なぜ進化が必要だったのでしょうか? 関数の実際の書き方と、その新旧について見ていきましょう。
function add(a, b) {
return a + b;
}
「関数宣言」と呼ばれる古い書き方です。 現在でも問題なく動きますが、少し記述が長くなります。
const add = (a, b) => {
return a + b;
};
ES6(2015)で登場した、現代のWeb開発で主流の書き方です。 関数を const(定数)に代入する形で作るため、すっきりと記述できます。
古い書き方には 「巻き上げ(Hoisting)」 という、予期せぬバグを引き起こす仕様がありました。
// 古い書き方:定義する前に呼び出せてしまう!(巻き上げ)
const result1 = oldAdd(10, 20); // 30 (なぜか動いてしまう)
function oldAdd(a, b) { return a + b; }
// 今の書き方:定義する前には使えない(安全!)
const result2 = newAdd(10, 20); // ❌ ちゃんとエラーになる!
const newAdd = (a, b) => { return a + b; };
アロー関数(と const)を使うことで、「上から下へ、必ず定義してから使う」 という他の言語では当たり前のルールが強制されるため、コードが格段に安全になります。
アロー関数には「省略記法」があり、これが多用されます。
const double = (num) => {
return num * 2;
};
処理が1行で、値を返すだけなら {} と return を消せます。
const double = (num) => num * 2;
ただし、コードの可読性は少し下がります。
以下の関数 getPrice を実行した結果は?
const getPrice = (price) => {
price * 1.1;
};
console.log(getPrice(100));
110100undefinednull正解: 3.
undefined
{} (波括弧) を書いた場合、明示的に return を書かないと戻り値は undefined になります。
// 正しい書き方 A (returnあり)
const getPrice = (price) => {
return price * 1.1;
};
// 正しい書き方 B (Implicit Return: 波括弧なし)
const getPrice = (price) => price * 1.1;
「あとで実行してもらうために渡す関数」 のことです。 他の関数に対して、引数として「これを実行してね」と関数を預けるイメージです。
const greet = () => console.log("こんにちは!");
// 3秒後に greet を実行してね、と渡す
setTimeout(greet, 3000);
アロー関数が好まれるもう一つの理由として、「コールバック関数」として使いやすい ということが挙げられます。
// 従来の書き方
setTimeout(function () {
console.log("1秒経過");
}, 1000);
// アロー関数
setTimeout(() => console.log("1秒経過"), 1000);
配列 とは同じ種類のデータが順番に並んだ 「データの連なり(リスト)」 です。 配列の操作には、for や while を使うこともできますが、JavaScriptには配列の操作に特化した 「配列メソッド」 が用意されています。
まずは「入れ物」としての使い方です。配列の要素には インデックス番号 が振られていて、0番目から数えます。 (だからこの講座は Section0 から始まっています)
const fruits = ["りんご", "バナナ", "みかん"];
// 0番目から数える (重要!)
console.log(fruits[0]); // "りんご"
console.log(fruits[1]); // "バナナ"
配列には、変数と同様に 「プロパティ」 が用意されています。 プロパティには () を付けません。最もよく使うのが length(長さ)です。
const fruits = ["りんご", "バナナ"];
console.log(fruits.length); // 2 (データの数)
「最後の要素を取り出す」など、要素の数が知りたい時に活躍します。
配列の中身を操作するための 「メソッド」 も用意されています。 メソッドは関数なので、使うときは () を付けます。
array.method()
const fruits = ["りんご", "バナナ"];
// push(): 配列の「末尾」にデータを追加する
fruits.push("みかん");
console.log(fruits); // ["りんご", "バナナ", "みかん"]
// pop(): 配列の「末尾」のデータを取り出して削除する
const lastFruit = fruits.pop();
console.log(lastFruit); // "みかん"
console.log(fruits); // ["りんご", "バナナ"]
.map() は「変換工場」です。
ベルトコンベア(配列)に乗って流れてくる材料(要素)を、一つずつ加工して、新しい製品(新しい配列)として送り出します。
[ , , ]カットして焼く[ , , ]数は変わりません。 中身の形が変わります。
const prices = [100, 200, 300];
// 全商品を1.1倍(税込)にする
const taxPrices = prices.map((price) => price * 1.1);
console.log(taxPrices); // [110, 220, 330]
map()の第一引数(上記では(price) => price * 1.1)は、アロー関数で、処理の内容を記述します。
.filter() は「セキュリティ・ゲート(選別機)」です。
条件(チケットや年齢制限など)に合致する要素だけを通し、合わないものを弾きます。
[ , , , ] (学生、先生、学生、不審者)学生か先生のみ通す[ , , ]数は減る可能性があります。 中身の形(人そのもの)は変わりません。
const scores = [50, 90, 40, 80];
// 60点以上だけ合格リストに入れる
const passed = scores.filter((score) => score >= 60);
console.log(passed); // [90, 80]
filterの第一引数(上記では(score) => score >= 60)もアロー関数で、条件を記述します。
「商品リストから300円以下のものだけを取り出したい」。 使うべきメソッドは?
const prices = [100, 500, 200];
const budgetPrices = prices.____((p) => p <= 300);
console.log(budgetPrices);
// @test: budgetPrices.length === 2 && budgetPrices.includes(100) && budgetPrices.includes(200)
.map().filter().push().forEach()正解: 2.
.filter()
「リスト変換」ならMap、「絞り込み・検索」ならFilter、と覚えましょう。
これらのメソッドは繋げることができます。 「60点以上(合格)の点数を抽出し、全員にボーナス(+10点)を加点したい」という場合:
const scores = [50, 90, 40, 80];
const result = scores
.filter((score) => score >= 60) // まず合格点だけを抽出 [90, 80]
.map((score) => score + 10); // さらにボーナスを加点 [100, 90]
console.log(result); // [100, 90]
処理の流れが左から右へ(上から下へ)流れるように読めるのが特徴です。
const array = [5, 12, 8, 130, 44];
const found = array.find((element) => element > 10);
console.log(found);
「条件に合う最初のひとつを探す」 配列全体ではなく、特定の1件(例:IDが一致するユーザー)が欲しい時に使います。戻り値は true か false ではなく、要素そのもの(見つからなければ undefined)です。
const array = [5, 12, 8, 130, 44];
const hasElement = array.includes(8);
console.log(hasElement);
「含まれているかチェックする」 単純に true か false が返ります。 「許可リストに入っているか?」などの権限チェックによく使います。
... (ドット3つ) を使うことで、配列の中身を 「展開(スプレッド)」 して別の配列に合体させることができます。 今後の開発で頻繁に登場する便利な構文です。
const listA = ["Apple", "Banana"];
const listB = ["Cherry"];
// リストAとリストBの中身を展開し、間に "Orange" を挟んで合体
const combined = [...listA, "Orange", ...listB];
console.log(combined);
// ["Apple", "Banana", "Orange", "Cherry"]
このセクションで、 「動的なWebアプリ」 を作るための土台が組み上がりました。
&&, ||)、Null合成(??)で、条件分岐を自在に操る。map, filter)で、リストデータを華麗に変換・抽出する。次回は、JavaScriptの総仕上げとして、より複雑なデータ構造である 「オブジェクト」 と 「データの不変性(Immutability)」 について学びます。