継承のブラウザ挙動/実装演習

親と子のメソッドが重なるコードを、呼出し・初期化・戻り値の三つに分けて追います。多段継承、static、親メソッドの更新を組み合わせ、どの値が最終結果になるかを確かめます。

この単元で学ぶこと

  • constructorの実行順と引数を計算する
  • 多段のsuper呼出しとstaticのthisを追う
  • 親の変更と例外が派生側へ与える影響を説明する

本文解説

引数の加工と初期化を順に計算する 親Aがconstructor(n){this.n=n*2;}、子Bがconstructor(n){super(n+1);this.n+=3;}ならnew B(4).nは13です。子が4を受け、親へ5を渡し、親が10にして戻り、子が3を足します。単にソースの上から数字だけを拾わず、引数の受渡しを矢印にします。

super前にできる処理 派生constructorのsuper前でも、引数の検査や外部配列への記録など、thisを使わない処理は行えます。log.push("before");super();log.push("after");なら親がAを記録するとbefore,A,afterです。「superより前には一切の文を書けない」という暗記では、thisが未初期化という本当の理由を見失います。

多段継承の戻り順 A.value()がA、B.value()がsuper.value()+"B"、C.value()がsuper.value()+"C"を返すとします。new C().value()の呼出しはC→B→Aと進み、戻るときにA→AB→ABCと結果を作ります。呼出す順と文字を付け足す順は逆方向です。superは一段上を起点にするため中間のBを飛ばしません。

メソッドの探索は後からも変わる A.prototype.mを新しい関数へ置き換えれば、子のsuper.m()も現在のその関数を使います。親が5を返し、子がsuper.m()*2なら結果は10です。またdelete B.prototype.mで子の上書きを消すと、b.m()は親のmを探索します。既存実体が古いメソッドをコピーして固定しているわけではありません。

staticでも受け手を分ける 親のstatic read(){return this.label;}をB.read()で呼ぶとthisはBです。A.label="A"、B.label="B"なら結果はBです。子のstaticからsuper.n()を呼ぶ場合、探すのはA.prototypeでなく親コンストラクタA側です。実体メソッドの経路とstaticの経路を二本で確認します。

superの探索先とcallの受け手 Bのm(){return super.m()+1;}をconst f=B.prototype.m;で取り出してf.call({n:10})と呼べます。親mがthis.nを返すなら11です。superで親を探す位置はメソッドの定義に結び付いたままで、thisはcallが指定します。superを「thisの親」とだけ覚えると、この二つを混同します。

生成ごとの状態と親の失敗 親constructorでthis.items=[]を作れば、子の実体a,bは別配列を持ちます。一方、親constructorがthrowした場合、子のsuper後の行は正常な続きとして実行されません。外側のcatchへ移り、失敗した生成の途中へ戻るわけでもありません。初期化済みの実体を得た前提で処理を続けないことが重要です。

継承関係を逆向きにしない new B()は通常AとB両方のinstanceofを満たしますが、new A()がBに属するとは限りません。親から子への特化という方向があります。値がないときは実体の所有プロパティ、子prototype、親prototypeの順に確認し、上書きの有無と構築時の初期化をそれぞれ切り分けます。

図解

new B(4)の初期化
親の結果を受けてから派生側の残りを実行する。

重要ポイント

  • 親へ渡す前の計算と親から戻った後の計算を分ける。
  • super前でもthisを使わない処理は可能。
  • staticのthisも呼出しの受け手で決まる。
  • 親のthrow後に派生constructorの正常な続きを実行しない。

間違えやすい点

  • superの探索位置とthisを同一視しない。
  • 親実体を必ず派生型だと判断しない。
  • 削除後にどの段階のメソッドが見えるか確認する。

用語解説

多段継承
CがBを、BがAを継承するように複数段の探索関係を作ること。
初期化順序
親へ渡す処理、親の構築、派生側の追加処理が実行される順番。
伝播
捕捉されていない例外などが呼出し元へ伝わること。

関連教材

参考資料

教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。

確認問題の出題・採点や学習履歴の保存にはログインが必要です。