本セクションでは、データを動的に処理するための「JavaScriptの基本ロジック」を学びます。

  1. 制御構文 (Control Flow)
    • if文, ショートサーキット(&&, ||), Null合成演算子(??)
  2. 関数 (Functions) の進化
    • 関数とは?, アロー関数, コールバック
  3. 配列とその操作
    • 配列の基本, プロパティ, メソッド(map, filter, find)

プログラムは一本道ではありません。「もし在庫があれば」「もしエラーなら」といった分岐が必要です。

1-1. 基本の if 文

const score = 85;

// 条件式が true の場合のみ実行される
if (score >= 80) {
  console.log("合格!おめでとう");
} else {
  // 条件式が false の場合
  console.log("不合格...再挑戦しよう");
}

読みやすいですが、条件が増えると行数が長くなりがちです。

ロジックの深掘り (Short-Circuit & Nullish)

論理演算子 (&&, ||) は、単なる true/false 判定以上のことができます。

1-2. ショートサーキット評価 : AND (&&) (1/2)

「左から順に見て、結果が決まった瞬間に止まる」 性質のことです。

1-2. ショートサーキット評価 : AND (&&) (2/2)

const isLoggedIn = true;
const userName = "Shake";

// isLoggedIn が true なので、右側の "Shake" が結果になる
const result = isLoggedIn && userName;
console.log(result); // "Shake"

1-3. ショートサーキット評価 : 実践活用

「条件を満たす時だけ実行する(満たさない時は何もしない)」場合に便利です。

const debugMode = true;

// debugModeがONの時だけログを出す
debugMode && console.log("現在はデバッグモードです");

if (debugMode) { ... } と書くよりも短く、意図が明確になります。

1-4. デフォルト値の設定:OR演算 (||)

|| は「左側が Falsy(無効な値) なら、右側の予備を使う」という動きをします。 これを利用して「デフォルト(初期値)」を設定することがよくあります。

// inputName が未入力("")や未定義(undefined)なら "ゲスト" にする
const inputName = "";
const displayName = inputName || "ゲスト";

console.log(displayName); // "ゲスト" (空文字は無効扱いになる)

1-5. OR演算 (||) の思わぬ落とし穴

||0""(空文字)も「無効」と判定してしまうため、数値の0 を扱うアプリ(点数や在庫など)ではバグの原因になります。

// 「0点」という立派な記録なのに...
const score = 0;

// 0 は Falsy なので、予備の値(10)が採用されてしまう!
const displayScore = score || 10;
console.log(displayScore); // 10 (0点のはずなのに上書きされた)

1-6. 救世主:Null合成演算子 (??)

この問題を解決するために登場したのが ?? です。 「完全に無 (null か undefined)」の時だけ 右側の予備を採用します。

const score = 0;

// 0 は「無」ではないので、そのまま採用される!
const displayScore = score ?? 10;
console.log(displayScore); // 0 (正しい!)

モダンな開発では、予期せぬバグを防ぐために基本的に ?? を推奨します。

どちらも「予備の値を設定する」役割ですが、「0 や 空文字 を有効な値として認めるか?」 が最大の違いです。

演算子

右側(予備)を採用する条件

特徴

||

Falsy (0, "", null, undefined)

0"" も「無効」として弾く

??

Nullish (null, undefined)

0"" は「有効」として認める

2-1. 関数 (Functions) とは? (1/2)

関数とは 「複数の処理(手順)をひとつにまとめて、名前をつける」 仕組みです。 例えば「お風呂に入る」という行動を考えてみましょう。

これを、「お風呂に入る」 という一言にまとめるためのものが、「関数」 です。

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();

いつもお風呂に入る時にわざわざ手順を全て説明しないように、複数の処理をまとめて一言で呼べるようにしたのが、「関数」 という概念です。

2-1. 関数 (Functions) とは? (2/2)

もう一つの重要な役割が 「入力(引数)を受け取り、出力(戻り値)を返す」 ことです。

alt text

「自動販売機」 をイメージすると分かりやすいです。

// お金(money)を受け取って、結果(戻り値)を返す関数
function buyDrink(money) {
  if (money >= 150) {
    return "コーラ"; // 外に結果を返す
  } else {
    return "お金が足りませんでした";
  }
}
const myDrink = buyDrink(200); // 200円を入れる
console.log(myDrink); // "コーラ"

2-2. 関数の歴史と進化

JavaScriptの関数は、時代とともに書き方が進化してきました。 なぜ進化が必要だったのでしょうか? 関数の実際の書き方と、その新旧について見ていきましょう。

2-3. 昔の書き方:関数宣言 (Function Declaration)

function add(a, b) {
  return a + b;
}

「関数宣言」と呼ばれる古い書き方です。 現在でも問題なく動きますが、少し記述が長くなります。

2-4. 今の書き方:アロー関数 (Arrow Functions)

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)を使うことで、「上から下へ、必ず定義してから使う」 という他の言語では当たり前のルールが強制されるため、コードが格段に安全になります。

2-5. アロー関数の構文バリエーション (1/2)

アロー関数には「省略記法」があり、これが多用されます。

基本形

const double = (num) => {
  return num * 2;
};

省略形

処理が1行で、値を返すだけなら {}return を消せます。

const double = (num) => num * 2;

ただし、コードの可読性は少し下がります。

以下の関数 getPrice を実行した結果は?

const getPrice = (price) => {
  price * 1.1;
};
console.log(getPrice(100));
  1. 110
  2. 100
  3. undefined
  4. null

正解: 3.

undefined

{} (波括弧) を書いた場合、明示的に return を書かないと戻り値は undefined になります。

// 正しい書き方 A (returnあり)
const getPrice = (price) => {
  return price * 1.1;
};

// 正しい書き方 B (Implicit Return: 波括弧なし)
const getPrice = (price) => price * 1.1;

2-6. コールバック関数とは? (1/2)

「あとで実行してもらうために渡す関数」 のことです。 他の関数に対して、引数として「これを実行してね」と関数を預けるイメージです。

身近な例:

2-6. コールバック関数とは? (2/2)

基本コード:

const greet = () => console.log("こんにちは!");

// 3秒後に greet を実行してね、と渡す
setTimeout(greet, 3000);

2-7. なぜアロー関数が好まれるのか? (1/2)

アロー関数が好まれるもう一つの理由として、「コールバック関数」として使いやすい ということが挙げられます。

// 従来の書き方
setTimeout(function () {
  console.log("1秒経過");
}, 1000);

// アロー関数
setTimeout(() => console.log("1秒経過"), 1000);

配列 とは同じ種類のデータが順番に並んだ 「データの連なり(リスト)」 です。 配列の操作には、forwhile を使うこともできますが、JavaScriptには配列の操作に特化した 「配列メソッド」 が用意されています。

3-1. 配列の基本

まずは「入れ物」としての使い方です。配列の要素には インデックス番号 が振られていて、0番目から数えます。 (だからこの講座は Section0 から始まっています)

const fruits = ["りんご", "バナナ", "みかん"];

// 0番目から数える (重要!)
console.log(fruits[0]); // "りんご"
console.log(fruits[1]); // "バナナ"

3-2. 配列が持つプロパティ

配列には、変数と同様に 「プロパティ」 が用意されています。 プロパティには () を付けません。最もよく使うのが length(長さ)です。

const fruits = ["りんご", "バナナ"];
console.log(fruits.length); // 2 (データの数)

「最後の要素を取り出す」など、要素の数が知りたい時に活躍します。

3-3. 配列の操作メソッド (push / pop)

配列の中身を操作するための 「メソッド」 も用意されています。 メソッドは関数なので、使うときは () を付けます。

array.method()

配列のメソッド - push/pop

const fruits = ["りんご", "バナナ"];

// push(): 配列の「末尾」にデータを追加する
fruits.push("みかん"); 
console.log(fruits); // ["りんご", "バナナ", "みかん"]

// pop(): 配列の「末尾」のデータを取り出して削除する
const lastFruit = fruits.pop();
console.log(lastFruit); // "みかん"
console.log(fruits); // ["りんご", "バナナ"]

3-4. 配列のメソッド - map (1/2)

.map() は「変換工場」です。

ベルトコンベア(配列)に乗って流れてくる材料(要素)を、一つずつ加工して、新しい製品(新しい配列)として送り出します。

数は変わりません。 中身の形が変わります。

3-5. 配列のメソッド - 実装 (2/2)

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)は、アロー関数で、処理の内容を記述します。

3-6. 配列のメソッド - filter (1/2)

.filter() は「セキュリティ・ゲート(選別機)」です。

条件(チケットや年齢制限など)に合致する要素だけを通し、合わないものを弾きます。

数は減る可能性があります。 中身の形(人そのもの)は変わりません。

3-6. 配列のメソッド - filter (2/2)

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)
  1. .map()
  2. .filter()
  3. .push()
  4. .forEach()

正解: 2.

.filter()

「リスト変換」ならMap、「絞り込み・検索」ならFilter、と覚えましょう。

3-6. メソッドチェーン (組み合わせ)

これらのメソッドは繋げることができます。 「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]

処理の流れが左から右へ(上から下へ)流れるように読めるのが特徴です。

3-7. その他の重要メソッド (.find, .includes)

.find() : 探索

const array = [5, 12, 8, 130, 44];

const found = array.find((element) => element > 10);
console.log(found);

「条件に合う最初のひとつを探す」 配列全体ではなく、特定の1件(例:IDが一致するユーザー)が欲しい時に使います。戻り値は truefalse ではなく、要素そのもの(見つからなければ undefined)です。

.includes() : 包含チェック

const array = [5, 12, 8, 130, 44];

const hasElement = array.includes(8);

console.log(hasElement);

「含まれているかチェックする」 単純に truefalse が返ります。 「許可リストに入っているか?」などの権限チェックによく使います。

3-8. 配列のスプレッド構文 (Spread Syntax)

... (ドット3つ) を使うことで、配列の中身を 「展開(スプレッド)」 して別の配列に合体させることができます。 今後の開発で頻繁に登場する便利な構文です。

const listA = ["Apple", "Banana"];
const listB = ["Cherry"];

// リストAとリストBの中身を展開し、間に "Orange" を挟んで合体
const combined = [...listA, "Orange", ...listB];

console.log(combined); 
// ["Apple", "Banana", "Orange", "Cherry"]

このセクションで、 「動的なWebアプリ」 を作るための土台が組み上がりました。

  1. Logic: if文とショートサーキット(&&, ||)、Null合成(??)で、条件分岐を自在に操る。
  2. Functions: アロー関数とコールバックで、処理をコンパクトに定義して渡す。
  3. Data (Arrays): 配列の強力なメソッド(map, filter)で、リストデータを華麗に変換・抽出する。

次回は、JavaScriptの総仕上げとして、より複雑なデータ構造である 「オブジェクト」「データの不変性(Immutability)」 について学びます。