【JavaScript】クラスの書き方と使い方の基本
JavaScriptのクラスについて、基本的な書き方と使い方を解説します。オブジェクトの設計図となるクラスの定義方法、初期化を行うconstructor、機能を引き継ぐ「継承」、処理を上書きする「オーバーライド」まで、サンプルコードを使って段階的に学習できます。
開発環境
- OS: Windows10
- Editor: Visual Studio Code
- JavaScript: ES6以降
JavaScriptのクラスとは
クラスとは、プログラムの中で扱う様々な「モノ(オブジェクト)」を作るための、いわば「設計図」のようなものです。
クラスを使うと、あるモノが持つ情報(これを「プロパティ」と呼びます)と、その情報を扱うための処理(これを「メソッド」と呼びます)を、一つのまとまりとして管理できます。
クラスの役割とメリット
- 設計図としての役割:
- 一つのクラス(設計図)があれば、それをもとに同じ構造を持つ実体をいくつでも生成できます。この設計図から作られた実体のことを「インスタンス」と呼びます。
- 例えば、「車」というクラス(設計図)を一度定義しておけば、その設計図を基に「色: 赤」の車インスタンスや、「色: 青」の車インスタンスを簡単に作り出すことができます。
- プログラムの整理:
- 関連するデータ(プロパティ)と処理(メソッド)がひとまとめになっているため、プログラムの構造が整理され、見通しが良くなります。また、同じようなモノを何度も作る場合に、クラスを再利用することで効率的に開発を進めることができます。
クラス名の慣例(命名規則)
JavaScriptでクラスに名前を付けるときは、「パスカルケース (PascalCase)」という命名規則に従うのが一般的です。パスカルケースとは、複数の単語をつなげる際に、各単語の先頭の文字を大文字にする書き方です。
このルールを守ることで、他のプログラマーがコードを読んだときに、その名前が「クラス」を指しているものだとすぐに理解できます。これにより、コードの可読性が向上します。
- 具体的な例:
UserService(UserとServiceという単語の先頭を大文字にしています)ProductCardHttpManager
JavaScriptでのクラスの定義方法
JavaScriptにおいて、クラスはオブジェクトを生成するためのテンプレート(雛形)です。同じ構造を持つオブジェクトを効率的に作成するために使用します。クラスを定義するにはclassキーワードを使います。
クラスの基本的な構造は以下の通りです。
1class クラス名 { 2 constructor(引数1, 引数2, ...) { 3 // プロパティの初期化 4 } 5 6 メソッド名() { 7 // メソッドの処理内容 8 } 9}
このコードの各要素について説明します。
-
class クラス名クラスの定義を開始する部分です。クラス名には、作成したいクラスの名前を指定します。一般的に、クラス名の最初の文字は大文字で記述します。 -
constructorconstructor(コンストラクタ)は、クラスから新しいオブジェクトを生成する際に、初期化のために自動的に呼び出される特別なメソッドです。new演算子を使ってオブジェクトが作成されるときに一度だけ実行されます。ここで、オブジェクトが持つデータである「プロパティ」の初期値を設定します。引数を受け取ることで、オブジェクトごとに異なる初期値を与えることが可能です。 -
メソッド名()メソッドは、そのクラスから生成されたオブジェクトが実行できる処理(関数)のことです。オブジェクトの振る舞いを定義する役割を持ちます。クラス内には、複数のメソッドを定義できます。
サンプルコード
この記事では、JavaScriptの「クラス」という概念について、4つのサンプルコードを通して段階的に学習します。クラスは、オブジェクト(データと処理をまとめたもの)を効率的に作成するための設計図のようなものです。
javascript/chapter18/index.html
1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="UTF-8" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 <title>JavaScriptチュートリアル</title> 7 </head> 8 9 <body> 10 <h1>JavaScriptチュートリアル</h1> 11 <script src="./script01.js" defer></script> 12 <script src="./script02.js" defer></script> 13 <script src="./script03.js" defer></script> 14 <script src="./script04.js" defer></script> 15 </body> 16</html> 17
このHTMLファイルは、これから解説する4つのJavaScriptファイル(script01.jsからscript04.js)を読み込んでいます。defer属性は、HTMLの読み込みを妨げずにJavaScriptを実行するための記述です。ブラウザの開発者ツール(コンソール)を開くと、各スクリプトの実行結果を確認できます。
javascript/chapter18/script01.js
1// サンプルコード1: 基本的なインスタンスメソッド 2class Person1 { 3 info(name, age, gender) { 4 return `${name} さんは ${age} 歳の ${gender} です。`; 5 } 6} 7 8const person1 = new Person1(); 9console.log(person1.info("山田", 30, "男性")); 10
このコードでは、classを使ってPerson1というクラス(設計図)を定義しています。
infoは「メソッド」と呼ばれ、このクラスが持つ機能(処理)です。ここでは、名前・年齢・性別を受け取り、自己紹介文を作成して返します。new Person1()という記述で、Person1クラスからperson1という「インスタンス」(設計図から作られた実体)を生成しています。person1.info(...)のように、生成したインスタンスからメソッドを呼び出し、必要な情報(引数)を渡して実行しています。
javascript/chapter18/script02.js
1// サンプルコード2: コンストラクタ(初期化処理) 2class Person2 { 3 constructor(name, age, gender) { 4 this.name = name; 5 this.age = age; 6 this.gender = gender; 7 } 8 9 info() { 10 return `${this.name} さんは ${this.age} 歳の ${this.gender} です。`; 11 } 12} 13 14const person2 = new Person2("山田", 30, "男性"); 15console.log(person2.info()); 16
このコードでは、「コンストラクタ」という仕組みを使っています。
constructorは、newを使ってインスタンスが生成される際に、自動的に一度だけ実行される特別なメソッドです。主に初期設定に使われます。- インスタンス生成時(
new Person2(...))に渡された情報を、this.name = name;のようにして、インスタンス自身のデータ(プロパティ)として保持させています。thisは「インスタンス自身」を指します。 infoメソッドは、引数を受け取る代わりに、インスタンスが保持しているthis.nameなどのプロパティを使って自己紹介文を生成します。- これにより、一度インスタンスに情報をセットすれば、メソッドを呼び出す際に毎回情報を渡す必要がなくなります。
javascript/chapter18/script03.js
1// サンプルコード3: クラスの継承 2class Person3 { 3 constructor(name, age, gender) { 4 this.name = name; 5 this.age = age; 6 this.gender = gender; 7 } 8 9 info() { 10 return `${this.name} さんは ${this.age} 歳の ${this.gender} です。`; 11 } 12} 13 14class User extends Person3 { 15 // Person3の機能をすべて継承 16} 17 18const user1 = new User("山田", 30, "男性"); 19console.log(user1.info()); 20
このコードは、クラスの「継承」という機能を示しています。
extendsというキーワードを使うことで、あるクラスが持つ機能(メソッドやプロパティ)を別のクラスに引き継がせることができます。- ここでは、
UserクラスがPerson3クラスを継承しています。このとき、Person3を「親クラス」、Userを「子クラス」と呼びます。 Userクラスの定義の中身は空ですが、親クラスであるPerson3のconstructorやinfoメソッドをすべて受け継いでいます。- そのため、
new User(...)でインスタンスを生成したり、user1.info()を呼び出したりすることが可能です。継承は、コードの再利用性を高めるために非常に有効な機能です。
javascript/chapter18/script04.js
1// サンプルコード4: メソッドのオーバーライド 2class Person4 { 3 constructor(name, age, gender) { 4 this.name = name; 5 this.age = age; 6 this.gender = gender; 7 } 8 9 info() { 10 return `${this.name} さんは ${this.age} 歳の ${this.gender} です。`; 11 } 12} 13 14 15class UserOverride extends Person4 { 16 info() { 17 return `ユーザーの ${this.name} さんは ${this.age} 歳の ${this.gender} です。`; 18 } 19} 20 21const user2 = new UserOverride("山田", 30, "男性"); 22console.log(user2.info()); 23
このコードでは、「オーバーライド」という機能を使っています。
- オーバーライドとは、親クラスから継承したメソッドを、子クラスで同じ名前のメソッドを定義し直すことで、処理内容を上書きすることです。
UserOverrideクラスはPerson4クラスを継承していますが、その中でinfoメソッドを再定義しています。user2.info()を呼び出すと、親クラスのinfoメソッドではなく、子クラスであるUserOverrideクラスで再定義されたinfoメソッドが実行されます。- その結果、コンソールに出力される文字列が「ユーザーの〜」という独自の形式に変わります。このように、基本的な機能は継承しつつ、子クラス独自の振る舞いを加えたい場合にオーバーライドが使われます。
おわりに
この記事では、JavaScriptにおけるクラスの基本的な書き方と使い方を学びました。classキーワードでオブジェクトの設計図を定義し、constructorでインスタンス作成時に初期値を設定する方法を確認しました。さらに、extendsを用いてクラスの機能を引き継ぐ「継承」や、継承したメソッドの処理を上書きする「オーバーライド」といった応用的な概念についても学習しました。これらの機能を活用することで、プログラムの再利用性が高まり、コードをより整理された状態に保つことができます。