新・JavaScript文法（1）：モダンな書き方

## 本シリーズについて

本シリーズの記事は、2016年ごろにQiitaで公開した、ES5ベースのJavaScript文法に関する記事を、執筆開始時点（2025年1月）でのモダンなJavaScript文法の内容でリライトしました。

自分自身がモダンな書き方を改めて知っておきたかった、つまり自分のためというのがリライトの主な目的です。ある程度は知っていて、調べた内容をプラスしてまとめているため、後の回で紹介する内容を手前の回で触れるなどしていますが、その点はご了承ください。

なお、本記事の執筆時点で筆者は会社員ですが、所属企業ならびに運営サービスとは一切関係なく、あくまでも過去の記事のリライトを目的として執筆・公開しています。

## 目次

1. モダンな書き方（本記事）
2. [文字列／演算子／型変換の基礎](https://qiita.com/azmnc/items/ef5969f745d45f582163)
3. [制御構文とループ処理の基本](https://qiita.com/azmnc/items/dbfa749aba34a1ad8fa3)
4. [配列の基本とモダンな操作](https://qiita.com/azmnc/items/810f1334d33fccfbf8c1)
5. [関数の基本とアロー関数](https://qiita.com/azmnc/items/28e7f9c02e30e9cfc3ed)
6. [スコープとクロージャ](https://qiita.com/azmnc/items/a678261bde849c32c7d1)

※全12回予定で制作中

## 本記事の概要

本記事では、JavaScriptの基本的な文法と書き方を扱います。

## なぜJavaScriptを学ぶのか

JavaScriptは、以下のような特徴から、プログラミング学習の第一歩として最適な言語の1つです。

1. **導入の手軽さ**
   - ブラウザさえあれば始められる
   - 特別なコンパイラが不要
   - 結果をすぐに確認できる
2. **幅広い活用場面**
   - Webサイトの対話機能の実装
   - Node.jsを使用したサーバー開発
   - モバイルアプリケーション開発 (React Nativeなど)
   - デスクトップアプリケーション開発 (Electronなど)
3. **豊富な学習リソース**
   - 多くの無料教材やチュートリアルが利用可能
   - 大きなコミュニティによるサポート
   - 実践的なサンプルコードが豊富
4. **高い求人需要**
   - Webフロントエンドエンジニア
   - フルスタックエンジニアへの発展も可能

## JavaScriptの特徴

### 言語としての特徴

1. **動的型付け**
   - C言語などのように変数の型を事前に宣言する必要がない
   - 柔軟な開発が可能
2. **マルチパラダイムプログラミング言語**
   - 手続き型プログラミング
   - オブジェクト指向プログラミング
   - 関数型プログラミング

### ECMAScriptとの関係

JavaScriptの核となる言語仕様は「ECMAScript」として標準化されています。

- **歴史的な転換点**：ES2015（ES6）で大規模アップデート
- **継続的な進化**：毎年新機能が追加（ES2016以降）
- **ブラウザサポート**：モダンブラウザはECMAScriptの仕様に沿って新機能を順次実装

## 開発環境の準備

### 1. ブラウザの開発者ツールを使う方法（推奨）

（1）ブラウザを起動し、F12キーを押す（もしくは、Windowsは `Ctrl + Shift + I`、Macは `Cmd + Option + I`）
（2）「Console」タブを選択
（3）コードを入力して実行

```javascript
// ConsoleタブでHello, World!を表示
console.log('Hello, World!');  // Enter（Return）キーを押すと実行される
```

### 2. Visual Studio Codeを使う方法（本格的な開発向け）

（1）Visual Studio Code（VSCode）をインストール（[https://code.visualstudio.com/](https://code.visualstudio.com/)）
（2）VSCodeで新規フォルダを作成
（3）新規ファイル「index.html」を作成：

```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>JavaScript学習</title>
</head>
<body>
    <h1>JavaScript学習環境</h1>
    <script src="main.js"></script>
</body>
</html>
```

（4）新規ファイル「main.js」を作成：

```javascript
console.log('Hello, World from VS Code!');
```

（5）Live Server拡張機能をインストール：

1. VSCodeの拡張機能タブで「Live Server」を検索
2. インストールして、VSCodeで`index.html`を開き、画面右下にある「Go Live」をクリック

## 基本的な書き方

### コメント

プログラムの説明や備忘録として、コメントを記述できます。

```javascript
// 1行コメント - 簡単な説明に

/* 
  複数行の
  コメント
  詳しい説明に
*/

// TODO: あとで実装する内容を記述
// FIXME: 修正が必要な箇所を記述
```

### コンソール出力

```javascript
// 基本的な出力
console.log('Hello!');  // Hello!

// 複数の値を出力
console.log('数値:', 42);  // 数値: 42

// 変数の値を埋め込んで出力
const name = 'JavaScript';
console.log(`言語名: ${name}`);  // 言語名: JavaScript

// デバッグ情報の出力
console.info('情報メッセージ');
console.warn('警告メッセージ');
console.error('エラーメッセージ');
```

## 変数宣言

### モダンな変数宣言：letとconst

JavaScriptでは、`let` と `const` を使って変数を宣言します。

```javascript
// 1. constを優先して使用（推奨）
const fixedValue = 42;        // 再代入できない変数
const taxRate = 0.1;          // 定数として使用
const user = {                // オブジェクトも定数として
    name: 'Alice',
    age: 25
};

// 2. 値が変更される場合のみletを使用
let score = 0;               // ゲームスコアなど
score = score + 10;          // 値の更新が必要な場合

let temperature = 20;        // 温度など変動する値
temperature = temperature + 1;  // 温度が1度上昇
```

### constを優先して使用する理由

1. **バグの防止**
   - 意図しない値の変更を防ぐ
   - コードの予測可能性が向上
2. **コードの意図の明確化**
   - 変更されない値だと明示できる
   - コードの理解がしやすくなる
3. **パフォーマンス**
   - JavaScriptエンジン（例: V8エンジン）は、constで宣言された変数を最適化しやすいため、処理速度の向上につながる場合がある

```javascript
// 良い例：constを使用
const API_URL = 'https://api.example.com';
const MAX_RETRY = 3;

// 必要な場合のみletを使用
let retryCount = 0;
while (retryCount < MAX_RETRY) {
    // リトライ処理
    retryCount++;
}
```

### varを使用しない理由

以前は `var` を使用していましたが、以下の問題があるため現在は非推奨です。

```javascript
// 問題1: 同じ変数を再宣言できてしまう
var x = 1;
var x = 2;  // エラーにならない

// 問題2: ブロックスコープを持たない
if (true) {
    var y = 3;  // ブロックの外からアクセスできてしまう
}
console.log(y);  // 3が出力される

// 問題3: 巻き上げ（hoisting）による混乱
console.log(z);  // undefinedが出力される
var z = 5;      // 宣言がスコープの先頭に移動されるため、undefinedになる
```

## データ型の基本

JavaScriptには、以下の主要なデータ型があります。

```javascript
// 1. プリミティブ型（基本型）
const number = 42;             // 数値型
const text = "Hello";          // 文字列型
const isActive = true;         // 真偽値型
const empty = null;            // null
const notDefined = undefined;  // undefined

// 2. オブジェクト型
const user = {
    name: "JavaScript",
    year: 1995
};

// 3. 配列（オブジェクトの一種）
const numbers = [1, 2, 3]; // JavaScriptでは、配列も内部的にはオブジェクトとして扱われる

// 型の確認
console.log(typeof number);      // "number"
console.log(typeof text);        // "string"
console.log(typeof isActive);    // "boolean"
console.log(typeof user);        // "object"
console.log(typeof numbers);     // "object"
```

## モダンな演算子

### オプショナルチェーン演算子（?.）

オブジェクトのプロパティに安全にアクセスするための演算子です。

```javascript
// ユーザーデータの例
const user = {
    name: "Alice",
    address: {
        city: "Tokyo"
    }
};

// 従来の方法 - 冗長で読みにくい
const city1 = user && user.address && user.address.city;  // "Tokyo"

// オプショナルチェーン演算子を使用 - シンプルで安全
const city2 = user?.address?.city;  // "Tokyo"
const phone = user?.contact?.phone;  // undefined（エラーにならない）

// 実践的な例：ユーザープロフィールの表示
const getDisplayName = (user) => {
    return user?.nickname ?? user?.name ?? "匿名ユーザー";
};
const getUserImage = (user) => {
    return user?.profile?.imageURL;
}
console.log(getDisplayName({ name: "Bob" }));          // "Bob"
console.log(getDisplayName({ nickname: "Bobby" }));    // "Bobby"
console.log(getDisplayName({}));                       // "匿名ユーザー"
console.log(getUserImage({profile: { imageURL: "image.png"}})); // "image.png"
console.log(getUserImage({})); // undefined
```

### Null合体演算子（??）

`null` または `undefined` の場合にデフォルト値を設定する演算子です。

```javascript
// 基本的な使い方
const value1 = null ?? "デフォルト値";    // "デフォルト値"
const value2 = 0 ?? "デフォルト値";       // 0
const value3 = "" ?? "デフォルト値";      // ""

// ??と||の違い
// ||: falseとみなされる値（0, "", false, null, undefined）の場合にデフォルト値を返す
console.log(0 || "デフォルト値");      // "デフォルト値"
console.log("" || "デフォルト値");     // "デフォルト値"

// ??: null または undefined の場合のみデフォルト値を返す
console.log(0 ?? "デフォルト値");      // 0
console.log("" ?? "デフォルト値");     // ""

// 実践的な例：ユーザー設定の読み込み
const loadUserSettings = (settings) => {
    return {
        theme: settings?.theme ?? "light",
        fontSize: settings?.fontSize ?? 16,
        language: settings?.language ?? "ja"
    };
};

console.log(loadUserSettings({}));  
// { theme: "light", fontSize: 16, language: "ja" }

console.log(loadUserSettings({ theme: "dark", fontSize: 20 }));
// { theme: "dark", fontSize: 20, language: "ja" }
```

## 実践的なコード例

### 1. 基本的な計算プログラム

```javascript
// 円の面積を計算する関数
const calculateCircleArea = (radius) => {
    const PI = 3.14159;
    return PI * radius * radius;
};

// 使用例
console.log(calculateCircleArea(5));  // 78.53975

// 温度変換（摂氏→華氏）
const celsiusToFahrenheit = (celsius) => {
    return (celsius * 9/5) + 32;
};

// 使用例
console.log(celsiusToFahrenheit(25));  // 77
```

### 2. BMI計算プログラム

```javascript
const calculateBMI = (height, weight) => {
    // 入力値のバリデーション
    if (height <= 0 || weight <= 0) {
        return null;  // 不正な入力
    }
    
    // 身長をメートルに変換
    const heightInMeters = height / 100;
    
    // BMIの計算: 体重(kg) / 身長(m)の2乗
    const bmi = weight / (heightInMeters ** 2);
    
    // 適正体重の計算: 身長(m)の2乗 × 22
    const idealWeight = (heightInMeters ** 2) * 22;
    
    // BMIに基づく体型の判定
    let bodyType;
    if (bmi < 18.5) {
        bodyType = "低体重";
    } else if (bmi < 25) {
        bodyType = "普通体重";
    } else if (bmi < 30) {
        bodyType = "肥満（1度）";
    } else {
        bodyType = "肥満（2度以上）";
    }
    
    return {
        bmi: Math.round(bmi * 10) / 10,        // 小数点第1位まで
        idealWeight: Math.round(idealWeight),   // 整数に四捨五入
        bodyType
    };
};

// 使用例
const height = 170;  // cm
const weight = 65;   // kg

const result = calculateBMI(height, weight);
if (result) {
    console.log(`
        BMI: ${result.bmi}
        適正体重: ${result.idealWeight}kg
        体型: ${result.bodyType}
    `);
}
```

## 復習

### 問題

#### 1. 以下のコードを実行すると、どのような結果になるか

```javascript
let a = 5;
const b = 3;
a = a + b;
console.log(a);
```

#### 2. 次のコードの問題点を指摘して、修正する

```javascript
var x = 1;
var x = 2;
if (true) {
    var x = 3;
}
console.log(x);
```

#### 3. オプショナルチェーン演算子を使って、以下のコードを書き換える

```javascript
const user = {
    name: "Bob",
    address: {
        city: "Osaka"
    }
};

const city = user && user.address && user.address.city;
console.log(city);
```

#### 4. 消費税計算プログラムを作成する

##### 仕様

- 税率は10%
- 引数として価格を受け取り、税込価格を返す関数を作成
- 小数点以下は切り捨て
- オプションで軽減税率（8%）にも対応

### 解答例

#### 1. 変数の計算

```javascript
// 結果は8になります
// aに5が代入され、bの3と足されて8になります
```

#### 2. varの問題点の修正

```javascript
// 修正後のコード
// 問題点：varはブロックスコープを持たないため、予期せぬ値の変更につながる
//        また、再宣言を許容してしまうため、意図しない挙動が発生しやすい
let x = 1;        // letを使用
const INITIAL = 2; // 定数として定義
if (true) {
    let x = 3;    // ブロックスコープの変数
    console.log(x);  // 3
}
console.log(x);     // 1
```

#### 3. オプショナルチェーン演算子

```javascript
const user = {
    name: "Bob",
    address: {
        city: "Osaka"
    }
};

const city = user?.address?.city;
console.log(city);  // Osaka
```

#### 4. 消費税計算プログラム

```javascript
const calculateTax = (price, isReduced = false) => {
    // 税率の設定（軽減税率対応）
    const taxRate = isReduced ? 0.08 : 0.10;
    
    // 税込価格の計算（小数点以下切り捨て）
    const totalPrice = Math.floor(price * (1 + taxRate));
    
    return {
        originalPrice: price,
        taxRate: taxRate * 100 + '%',
        taxAmount: Math.floor(price * taxRate),
        totalPrice: totalPrice
    };
};

// 使用例
console.log(calculateTax(1000));  
// {
//   originalPrice: 1000,
//   taxRate: "10%",
//   taxAmount: 100,
//   totalPrice: 1100
// }

console.log(calculateTax(1000, true));  
// {
//   originalPrice: 1000,
//   taxRate: "8%",
//   taxAmount: 80,
//   totalPrice: 1080
// }
```

## まとめ

本記事の重要なポイントは、以下のとおりです。

1. **モダンな変数宣言**
   - `const`を優先して使用
   - 値の変更が必要な場合のみ`let`を使用
   - `var`は使用しない
2. **新しい演算子の活用**
   - オプショナルチェーン（?.）で安全にプロパティにアクセス
   - Null合体演算子（??）でデフォルト値を設定
3. **基本的なデータ型の理解**
   - プリミティブ型とオブジェクト型の区別
   - 型の確認方法（typeof）
4. **実践的なコーディング**
   - 関数を使った処理の部品化
   - エラーケースの考慮

次回は、文字列操作と型変換について扱います。