【JavaScript】クラス定義(コンストラクタ、継承)はどうする?

プログラミングのKnow-howを共有しましょう

【JavaScript】クラス定義(コンストラクタ、継承)はどうする?

スポンサーリンク

JavaScriptでのクラス定義について書いていきたいと思います。参考になれば幸いです。

JavaScriptにはオブジェクト指向の考え方があります。クラス定義、コンストラクタや継承などはどういう記述になるのでしょうか?見て行きましょう。

JavaScriptでのクラス定義

JavaScriptでクラスを定義する方法は単純、functionを使います。functionと言えばJavaScriptでいう関数定義で使う記述ですが、なんとクラス定義にも使ってしまうのです。以下のように定義します。

この定義では、「Person(人間)クラス」という大きな枠(クラス)を作成し、その枠を持った「Tanaka」と言う個体(インスタンス)を定義しています。
「Tanaka」は「田中(name)、男(sex)」という情報(プロパティ)を持ち、”hello”と話す能力(メソッド)を持っています。

行単位で見て行きましょう。

クラスの定義をしています。ご覧の通り、functionを使っていますね。
「this.〜」という変数がありますが、これはプロパティ(インスタンス特有の変数)の定義です。

クラスのメソッドを定義しています。Person(人間)というクラスに”hello”と話させるメソッド(能力)です。
「Person.prototype」が「これからPersonクラスのメソッドを定義しますよ」という部分で、「hello」がメソッドの名前です。

  • メソッドの定義にはprototype以外もある!?

2018年現在、よく見かけるのは上記の「prototype」です。しかし他の言語を試したことがある方なら、プロパティの定義と同様に「this」を使ってメソッドを定義してもいいじゃないか、と思うかもしれません。しかし両者には大きな違いがあるのです・・・。興味があれば以下の記事をどうぞ。

12行目で「Tanaka」というPersonクラスのインスタンスを定義しています。
その際に、引数として”田中”、”男”という文字列を与えていますね、これは3〜4行目の記述に繋がっていて、Tanakaはnameが”田中”、sexは”男”という初期情報を定義しています(コンストラクタ)

これでJavaScriptでクラスが定義できるようになりました。

JavaScriptでの継承

さて、JavaScriptでクラスの定義ができるようになりましたが、オブジェクト指向にはまだまだ重要な考え方があります。

それは親から子への引き継ぎ、つまり継承(オーバーライド)です。
もちろん、JavaScriptでも継承はできます。どのような記述になるのでしょうか?以下のソースを見てください。

今回は新たに「Student」というクラスを作成しました。前章の「クラス定義」で定義した「Person」(人間)でできること全てを「Student」(学生)でもできるように継承しています。

行単位で見ていきましょう。

Studentクラスを定義しています。ここで注目していただきたいのが、3行目のPerson.callの記述です。Personのコンストラクタ(nameとsexの定義)を継承しているのですが・・・いきなりcallなんて使われてもわかりませんよね。ということで簡単にcallの解説をしていきます。

function.callメソッドとは?

以下のような書き方をします。(この例ではfunctionを関数と捉えた方がわかりやすいです。)

“[使用したいfunction].call( [funtionの処理だけ利用したいオブジェクト] , [使用したいfunctionの引数内容] )”

要するに、「俺、この特技(使用したいfunction)持ってないんだけどさ、わざわざ身につける(定義)するのも面倒だしお前の特技を使わせてよ。結果だけもらうからさ。

というわがまま理論を通すことができる機能になっています。とても便利ですね。

上記の解説を踏まえた上で、Person.call(this,name,sex)と言う記述の各要素はそれぞれ何に当たるのかというと・・・

  • 使用したいfunction = Personというfunction。これは関数的にいうとthis.nameとthis.sexを定義する機能だけを持っています。(コンストラクタ)
  • functionの処理だけ利用したいオブジェクト = this(Student)のことです。
  • 使用したいfunctionの引数内容 = name,sexのことです。Personの引数はこの2つでしたね。

結果として、Studentというクラスはnameとsexの定義をPersonクラスの機能を使って行なっているわけです。

これでコンストラクタの継承はできました。続いてはメソッドの継承です。

Object.createというメソッドが出てきましたね。要するに、「StudentはPersonのprototypeメソッドを持つんだぞ」ということを宣言しています。
問題はその下の記述です。constractorというメソッドにわざわざ自分を定義しています。どうしてでしょう?

実は、functionは定義された時点で「prototype.constractor」というメソッドが自動で定義されていて、この値は定義された時点でのfunction自身が指定されます。
Person.prototype.constractorを使えばPersonを返しますし、Student.prototype.constractorを使えばStudentを返すべきなのです。

しかし、先ほど「StudentはPersonのprototypeメソッドを持つんだぞ」という宣言をしてしまいました。
この状態でStudent.prototype.constractorが呼ばれるとどうなってしまうのか・・・・Personと返ってきてしまいます。ここはStudentと返ってきて欲しいですね。

だから、上記のような記述をして「StudentはPersonのprototypeメソッドを持つんだぞ。だけどprototype.constractorはStudentだぞ。」という宣言をしています。

これでメソッドの継承は完了です。実際に継承してみましょう!

これでSuzukiと言うStudentクラスのインスタンスが定義されました!Personと比べると「3」というプロパティが増えていますね!

「クラス定義(コンストラクタ、継承)はどうする?」についてのノウハウは以上です。
よろしければ他のノウハウもみていってください。