PR

JavaScriptのクラスを基礎から学ぶ初心者向けガイド

JavaScriptのクラスを基礎から学ぶ初心者向けガイド JavaScript
広告

JavaScriptのクラスについて興味がありますか?オブジェクト指向プログラミング(OOP)に少し戸惑っていませんか?

もしそうなら、このガイドが役に立つはずです。本記事では、JavaScriptにおけるクラスの仕組みを基礎から解説し、最終的に簡単なToDoアプリを作成するところまでお手伝いします。

広告

JavaScriptにおける関数の基本

JavaScriptプログラミングの基本は「関数」です。最初のプログラムで関数を使うことはほぼ間違いありません。そのため、クラスを学ぶ前に、関数がどのように使われるのかをしっかりと理解しておきましょう。

例えば、ユーザーの名前を表示する関数は次のように書けます。

function greetUser(userName) {
  console.log("Hello, " + userName + "!");
}

greetUser("Saka"); // Hello, Saka!
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>関数の例</title>
  <style>
    #output {
      font-size: 24px;
      color: blue;
    }
  </style>
</head>
<body>
  <div id="output"></div> <!-- メッセージを表示する場所 -->

  <script>
    function greetUser(userName) {
      // HTML要素を操作してメッセージを表示
      document.getElementById("output").innerText = "Hello, " + userName + "!";
    }

    greetUser("Saka"); // 関数を呼び出し
  </script>
</body>
</html>

このように関数を使うことで、処理を細かく分割し、再利用性を高めることができます。しかし、アプリケーションが大きくなるにつれて、関数の数が増え、管理が難しくなることがあります。そのため、関数の設計や整理が重要になってきます。

JavaScriptのオブジェクトとは?

オブジェクトはJavaScriptの基本的なデータ構造の一つであり、データとそれに関連する機能をまとめるための方法です。オブジェクトは「プロパティ(属性)」と「メソッド(関数)」で構成されます。

次のようなオブジェクトを作成できます。

const person = {
  name: "Saka",
  greet: function() {
    console.log(`Hello, my name is ${this.name}`);
  }
};

person.greet(); // Hello, my name is Saka

ここで使用されているthisキーワードは、オブジェクト内からそのオブジェクト自身のプロパティにアクセスするために使われます。

この例では、this.namepersonオブジェクトのnameプロパティ("Saka")を参照しています。

しかし、同じようなオブジェクトを複数作成する場合、手作業で一つずつオブジェクトを定義するのは非効率的です。そこで、コンストラクタ関数クラスを使うことで、効率的にオブジェクトを作成できます。

広告

コンストラクタ関数:オブジェクトを作成する設計図

コンストラクタ関数を使った例を以下に示します。

// コンストラクタ関数
function Person(name) {
  this.name = name;
  this.greet = function() {
    console.log(`Hello, my name is ${this.name}`);
  };
}

// オブジェクトの作成
const person1 = new Person("Saka");
const person2 = new Person("Tomato");

person1.greet(); // Hello, my name is Saka
person2.greet(); // Hello, my name is Tomato

このように、コンストラクタ関数を使うことで、同じ構造を持つオブジェクトを簡単に複数作成できます。

ES6クラス:より簡潔な記法

ES6以降ではclass構文を使うことで、オブジェクト指向のコードをよりシンプルに書けるようになりました。

以下は、クラスを使った基本的な例です。

// クラスを使った例
class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

const person1 = new Person("Saka");
person1.greet(); // Hello, my name is Saka

このように、class構文を使うことで、コンストラクタやメソッドを明確に定義でき、コードの可読性が向上します。

クラスの継承

さらに、extendsキーワードを使うことで、既存のクラスを継承し、新しいクラスを作成できます。

以下は、Personクラスを継承してDeveloperクラスを作成する例です。

// Personクラスを先に定義
class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

// Developerクラスを定義
class Developer extends Person {
  constructor(name, language) {
    super(name); // 親クラスのコンストラクタを呼び出す
    this.language = language;
  }

  code() {
    console.log(`${this.name} is coding in ${this.language}`);
  }
}

const developer1 = new Developer("Saka", "JavaScript");
developer1.greet(); // Hello, my name is Saka
developer1.code();  // Saka is coding in JavaScript

ファイルが正しく読み込まれているか確認します。以下はHTMLファイルでの読み込み例です。

HTMLファイル

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>クラスの例</title>
</head>
<body>
  <script src="person.js"></script> <!-- Personクラスが定義されたファイル -->
  <script src="developer.js"></script> <!-- Developerクラスが定義されたファイル -->
  <script src="main.js"></script> <!-- クラスを使用するファイル -->
</body>
</html>

person.js(Personクラスの定義)

class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

developer.js(Developerクラスの定義)

class Developer extends Person {
  constructor(name, language) {
    super(name);
    this.language = language;
  }

  code() {
    console.log(`${this.name} is coding in ${this.language}`);
  }
}

main.js(クラスを使用)

const developer1 = new Developer("Saka", "JavaScript");
developer1.greet(); // Hello, my name is Saka
developer1.code();  // Saka is coding in JavaScript

モジュールを使用している場合

ES6モジュール(import/export)を使用している場合、クラスをエクスポートし、インポートする必要があります。

person.js(Personクラスのエクスポート)

export class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

developer.js(Developerクラスのエクスポート)

import { Person } from './person.js';

export class Developer extends Person {
  constructor(name, language) {
    super(name);
    this.language = language;
  }

  code() {
    console.log(`${this.name} is coding in ${this.language}`);
  }
}

main.js(クラスのインポートと使用)

import { Developer } from './developer.js';

const developer1 = new Developer("Saka", "JavaScript");
developer1.greet(); // Hello, my name is Saka
developer1.code();  // Saka is coding in JavaScript

HTMLファイル(モジュールを使用する場合)

<script type="module" src="main.js"></script>
広告

プロトタイプとメモリ効率の向上

JavaScriptでは、プロトタイプを活用することで、各オブジェクトに重複するメソッドを持たせずに済みます。これにより、メモリ効率が向上します。以下は、プロトタイプを使ってメソッドを共有する例です。

function Person(name) {
  this.name = name;
}

// プロトタイプにメソッドを追加
Person.prototype.greet = function() {
  console.log(`Hello, I'm ${this.name}`);
};

const alice = new Person("Saka");
alice.greet(); // Hello, I'm Saka

このように、greetメソッドをPerson.prototypeに追加することで、すべてのPersonオブジェクトが同じgreetメソッドを共有できます。これにより、メモリ使用量が削減され、パフォーマンスが向上します。

継承:一つのクラスから別のクラスを派生させる

JavaScriptでは、call()Object.create()を使って、簡単にクラスを継承できます。

以下は、Personクラスを継承してDeveloperクラスを作成する例です。

function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log(`Hello, I'm ${this.name}`);
};

// DeveloperクラスをPersonクラスから継承
function Developer(name, language) {
  // Personのコンストラクタを呼び出す
  Person.call(this, name);
  this.language = language;
}

// DeveloperのプロトタイプをPersonのプロトタイプにリンク
Developer.prototype = Object.create(Person.prototype);

// Developerのメソッドを追加
Developer.prototype.code = function() {
  console.log(`${this.name} is coding in ${this.language}`);
};

const Saka = new Developer("Saka", "JavaScript");
Saka.greet(); // Hello, I'm Saka
Saka.code();  // Saka is coding in JavaScript
  1. Person.call(this, name):
    • Personクラスのコンストラクタを呼び出し、Developerオブジェクトにnameプロパティを設定します。
  2. Object.create(Person.prototype):
    • DeveloperのプロトタイプをPersonのプロトタイプにリンクし、Personのメソッドを継承します。
  3. メソッドの追加:
    • Developerクラスに独自のメソッド(code)を追加できます。
  • プロトタイプチェーン:
    • JavaScriptのオブジェクトは、プロトタイプチェーンを通じてメソッドやプロパティを継承します。これにより、メモリ効率が向上し、コードの再利用性が高まります。
  • ES6クラスとの比較:
    • ES6のclass構文を使うと、プロトタイプベースの継承をより直感的に記述できます。以下は、同じ内容をclass構文で書いた例です。
class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`Hello, I'm ${this.name}`);
  }
}

class Developer extends Person {
  constructor(name, language) {
    super(name);
    this.language = language;
  }

  code() {
    console.log(`${this.name} is coding in ${this.language}`);
  }
}

const Saka = new Developer("Saka", "JavaScript");
Saka.greet(); // Hello, I'm Saka
Saka.code();  // Saka is coding in JavaScript
広告

クラスを活用したToDoアプリの作成

クラスを活用することで、小規模なアプリケーションも整理して実装できます。たとえば、ToDoアプリを作るのに適した設計として ToDo クラスと ToDoList クラスがあります。

class ToDo {
  constructor(description) {
    this.description = description;
    this.completed = false;
  }

  markComplete() {
    this.completed = true;
    console.log(`"${this.description}" marked as complete!`);
  }
}

さらに、ToDoのリストを管理するための ToDoList クラスも作成できます。

class ToDoList {
  constructor() {
    this.todos = [];
  }

  addTodo(description) {
    const newTodo = new ToDo(description);
    this.todos.push(newTodo);
  }

  listTodos() {
    return this.todos;
  }
}

その後、HTMLと連携させることで、ブラウザ上で動作するToDoアプリを作成できます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ToDoアプリ</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div>
        <h1>ToDoアプリ</h1>
        <input type="text" id="todoInput" placeholder="新しいToDoを入力">
        <button id="addButton">Add To-Do</button>
        <ul id="todoList"></ul>
    </div>

    <script>
        class ToDo {
            constructor(description) {
                this.description = description;
                this.completed = false;
            }

            markComplete() {
                this.completed = true;
                console.log(`"${this.description}" marked as complete!`);
            }
        }

        class ToDoList {
            constructor() {
                this.todos = [];
            }

            addTodo(description) {
                const newTodo = new ToDo(description);
                this.todos.push(newTodo);
                this.updateUI();
            }

            listTodos() {
                return this.todos;
            }

            updateUI() {
                const todoListElement = document.getElementById("todoList");
                todoListElement.innerHTML = ""; // リストをクリア

                this.todos.forEach((todo, index) => {
                    const li = document.createElement("li");
                    li.textContent = todo.description;
                    if (todo.completed) {
                        li.classList.add("completed");
                    }
                    li.addEventListener("click", () => {
                        todo.markComplete();
                        this.updateUI();
                    });
                    todoListElement.appendChild(li);
                });
            }
        }

        const myTodoList = new ToDoList();
        document.getElementById("addButton").addEventListener("click", () => {
            const desc = document.getElementById("todoInput").value;
            if (desc) {
                myTodoList.addTodo(desc);
                document.getElementById("todoInput").value = ""; // 入力ボックスをクリア
            }
        });
    </script>
</body>
</html>

ブラウザでhtmlファイルを開きます。

アプリの使用

テキストボックスにToDoを入力し、「Add To-Do」ボタンをクリックすると、ToDoがリストに追加されます。

リストの項目をクリックすると、そのToDoが完了済みとしてマークされ、文字に取り消し線が引かれます。

説明

ToDoクラス: 各ToDoアイテムを表します。description(説明)とcompleted(完了済みかどうか)のプロパティを持ちます。

ToDoListクラス: ToDoアイテムのリストを管理します。addTodoメソッドで新しいToDoを追加し、updateUIメソッドでUIを更新します。

HTML: ユーザーがToDoを入力し、追加するためのインターフェースを提供します。

JavaScript: ユーザーの操作に応じてToDoリストを更新し、UIに反映します。

これで、ブラウザ上で動作するシンプルなToDoアプリが完成します。

>> シンプルなToDoアプリのDEMO

広告

まとめ

JavaScriptのクラスは、オブジェクト指向プログラミング(OOP)の原則を取り入れながら、より読みやすく、管理しやすいコードを書くための優れた手段です。

クラスを使うことで、関連するデータと機能を一箇所にまとめ、コードの再利用性や保守性を高めることができます。

さらに、プロトタイプを理解することで、クラスが内部的にどのように動作しているのかをより深く理解できます。プロトタイプを活用することで、メモリ効率を向上させ、すべてのインスタンスが同じメソッドを共有できるようになります。

  • クラスとプロトタイプの関係:
    • ES6のclass構文は、内部的にはプロトタイプベースの継承を使用しています。そのため、クラスを使いながらも、プロトタイプの仕組みを理解しておくことが重要です。
  • OOPの原則:
    • カプセル化、継承、ポリモーフィズムといったOOPの原則をJavaScriptのクラスで実現できます。

以下のリンクでは、JavaScriptに関する記事をまとめています。各記事をクリックして、詳しい情報をご確認ください。

タイトルとURLをコピーしました