JavaScriptでは、親クラスを継承するのに下記のような方法をとります。
SubClass.prototype = new SuperClass();
しかし、この方法だとコンストラクタに引数を必要とする場合、
子クラスにはインスタンス化の際に指定することが出来ますが、
親クラスに指定する術がありません。
JavaScriptでは、子クラスをインスタンス化した際に指定した引数を
親クラスのコンストラクタにて使用したい場合は、
少し工夫が必要です。
今回は、そんな親クラスへ引数を渡す方法について解説します。
その前に、JavaScriptでのクラス定義方法を確認したい方は下記を参照してください。
JavaScriptのクラス定義方法を徹底解説!!
また、今回のテーマと同様に、継承関係にある親子クラスの扱い方として、親クラスの同名メソッドを呼ぶ方法についても
下記にて確認することが出来ます。
[JavaScript]子クラスから親クラスの同名メソッドを呼び出す方法
これらの事前知識を踏まえた上で読み進めて下さい。
prototypeのプロパティに関数オブジェクトを登録する
通常、JavaScriptの継承を行う際には、多くのブログでは下記の様に紹介されています。
SubClass.prototype = new SuperClass();
しかし、これでは親クラスをインスタンス化しているのがオブジェクト外ですので、
親クラスのインスタンス化時に引数を指定することが出来ません。
中には、親クラスと子クラスを包むラッパークラスを作成して対応している方もいますが、
それでは継承の意味があまり無く、だったら一つのクラスに纏めてしまえば?といった感覚です。
親クラスへ引数を渡す際に、上記のコードで問題となるのが、動的な引数を渡す必要があるのに、
処理が通るのが初回の構文解析時の一回だけと言う事です。
解決策としては、子クラスのprototypeにプロパティを作成し、そこへ親クラスのインスタンスではなく
親クラスの関数オブジェクトを指定します。
そして、自分の参照先の一つでもあるprototypeを通して設定したプロパティにアクセスし、
親クラスのコンストラクタへ引数を指定して起動します。
すると、親クラスのコンストラクタへ引数を指定出来、自分の状態を維持することが出来ます。
子クラスから親クラスのコンストラクタへ引数を渡す具体的な実装例
これまで解説してきた内容を踏まえ、実際にテストコードを作成してみました。
具体的には、下記のような処理です。
/* 親クラス ------------------------------------------------*/ function SuperClass( val ){ // メンバに保持 this.superClassVal = "superClass="+val; } /* 子クラス ------------------------------------------------*/ function SubClass( val ){ // 親クラスの初期化 this.superClass( val ); // メンバに保持 this.subClassVal = "subClass="+val; } // 親クラスの関数オブジェクトを子クラスのprototypeに対して // プロパティを設け、登録する SubClass.prototype.superClass = SuperClass; // 子クラスを引数付きでインスタンス化し、 // それぞれのプロパティを確認してみる var sub_class = new SubClass( "testData" ); console.log(sub_class.subClassVal); console.log(sub_class.superClassVal);
上記の実行結果としては、下記の様になるかと思います。
subClass=testData
superClass=testData
まず、親クラスを子クラスへ継承させる際に、
子クラスのprototypeにプロパティを設け、親クラスの関数オブジェクトを指定します。
SubClass.prototype.superClass = SuperClass;
すると、親クラスのコンストラクタ自体は
子クラスのコンストラクタ内にて下記の様に呼び出すことが出来ます。
this.superClass( val );
通常のメソッドコールと同じ様に扱いますので、子クラスのコンストラクタへ渡された引数を
そのまま親クラスへ渡すことが可能となります。
JavaScriptはとても柔軟な言語ですので、もっと良いやり方が他にもあるかも知れません。
もし、他の方法をご存知の方がいらっしゃいましたら、是非ともコメントにて
ご報告頂ければ幸いです。