JavaScriptはECMAscript2015に改定されたことによってクラスの定義の方法が変更されました。以前は特殊であったクラス定義の方法がわかりやすくなりました。クラスの定義によってコードの冗長化を防いだり、可読性を高めることができるので、しっかりと本記事で学習しましょう。
クラスとは?
JavaScriptにおけるクラスは厳密に言うと存在しません。代わりにプロトタイプというものがあり、それを便宜上クラスと読ばれます。クラスはオブジェクトの設計図のようなもので、インスタンス化をすることによってクラスに従ったオブジェクトを作成することができます。例えば以下のコードで実際にクラスを定義することができます。
class Book{ constructor(title,author,description){ this.title = title; this.author = author; this.description = description; } get title(){ return this._title; } set title(value){ this._title = value; } get author(){ return this._author; } set author(value){ this._author = value; } get description(){ return this._description; } set title(value){ this._description = value; } };
上から順に説明していきます。まず、class命令とクラス名Bookを定義します。その中にコンストラクターとゲッター・セッターを定義していきます。
コンストラクターの使い方
コンストラクターとはクラスを元にインスタンス(オブジェクト)を生成する際に、オブジェクトを初期化するメソッドのことです。
constructor(title,author,description){ this.title = title; this.author = author; this.description = description; };
コンストラクターの配下でのthisはコンストラクターで生成されるインスタンス自体を示します。thisにプロパティ名である「title、author、description」を設定することで、インスタンスのプロパティを設定することができます。コンストラクターでは自動的にthisに設定された値を返すので、戻り値は不要です。
コンストラクターの設定は次のように簡略化することができます。
constructor(title,author,description){ Object.assign(this, {title,author,description}); };
Object.assignメソッドはオブジェクト同士を結合させるメソッドです。thisは現在のインスタンスを意味していて、引数に渡された「title、author、description」の値を現在のインスタンスにまとめて結合させる処理を行っています。
{title,author,description}
上記のコードはオブジェクトの省略した構文で次のコードと同じです。
{ title:title, author:author, description:description };
インスタンス化
インスタンス化はnew演算子の後にクラス名を記述することによって行います。
let novel = new Book( '小説', '芥川', '歴史に残る名作です。' ); console.log(novel.title) //結果:小説
classの引数に設定したい値をを記述していきます。インスタンス化によってコンストラクターで設定したプロパティ名を持つインスタンス(オブジェクト)を生成することができます。
ゲッター・セッター
ゲッターとセッターはプロパティを取得・設定する際に使用するメソッドのことです。get・set命令で定義することができます。
get title(){ return this._title; } set title(value){ this._title = value; }
なぜゲッターとセッターを設定するのかというと値のアクセスを制限することによって、データの保守性を保つためです。this._titleのような記法になっているのはクラス外からアクセスしないように意思表示を指定いるためです。ゲッターはインスタンスの_titleの値を返しています。セッターは引数valueを_titleに代入するメソッドです。titleだけでなく他のプロパティ名も同様にセッターとゲッターを定義することができます。ゲッターとセッターはメソッドですが、通常のメソッドとは違って次のように変数のように使用できます。
novel.title ='すごい小説'; console.log(novel.title); //結果:すごい小説
上記のようにセッターは代入演算子によって使用することができます。
クラスの継承
継承は元のクラスやオブジェクトで定義されたゲッターやセッター、関数、値を引き継いで、新たなクラスを定義する機能のことです。例えばAnimalクラスからDogクラスに継承したいときは次のように記述します。
class Animal{ constructor(name){ this.name = name; } get name(){ return this._name; } set name(value){ this._name = value; } }; class Dog extends Animal{ run(){ return `${this.name}はよく走ります。` } }; let pug = new Dog('パグ'); console.log(pug.name);//結果:パグ console.log(pug.run());//結果:パグはよく走ります。
class命令とクラス名を宣言した後に、extendsキーワードで継承したいclassのクラス名を指定することによって継承することができます。継承元のゲッターも使用することできることがわかります。上記のような一つのクラスから継承するのを単一継承といいます。他のプログラミング言語では複数のクラスを同時に継承する多重継承が可能な場合が多いですが、JavaScriptでは多重継承には対応していません。
JavaScriptにおけるオブジェクト指向
JavaScriptにおけるオブジェクトは機能的には連想配列と同じです。連想配列に関する詳細は「JavaScriptでの連想配列の書き方」を確認してください。しかし、オブジェクトは連想配列とは違って、一つの物を表す情報を持ったモノそのものであって、連想配列のような関連したただの各情報の集まりとは意味的には違います。先ほど説明したnew演算子によるインスタンス化はクラス(オブジェクト)をコピーして、オブジェクトを複製するモノだったのです。こうしたオブジェクトを中心にコードを記述していく手法をオブジェクト思考と言います。JavaScriptにおいてはクラスもインスタンスも全てオブジェクトであり、他の言語と少し違っていることに注意しましょう。
この記事のまとめ
本記事ではJavaScriptのクラスの扱い方について学びました。クラスはECMAscript2015になった初めて実装された機能なので、昔の技術書などには載っていないと思います。新しい機能ですがオブジェクト志向のプログラミングを実現するのに必須の機能なので、しっかりと勉強しましょう。最後に本記事のまとめです。
- クラスはオブジェクトの設計図のようなモノである
- new演算子を使って、指定したクラスからオブジェクトのコピーを作ることができる(インスタンス化)
- インスタンス化する際に定義したコンストラクターによって初期化することができる
- クラスにゲッターとセッターを設定することで、クラス外からのアクセスを防ぎ、コードの保守性を保つことができる
- 継承を使うことによって元のクラスのメソッドやプロパティを引き継いだ新たなクラスを作成することができる
- JavaScriptはオブジェクトを中心にプログラミングをするオブジェクト志向で作られているが、他の言語と一部異なる点に注意する
ぜひ、クラスの操作を利用して、JavaScriptをさらに便利に使用しましょう!!