[JS] Overrideしたときの挙動が異なる
以下のクラスとそれを呼びだすコードがあります。
import * as THREE from "three" import { VRMLookAt } from "@pixiv/three-vrm" const _v3A = new THREE.Vector3() export class CustomVRMLookAt extends VRMLookAt { constructor(humanoid: any, applier: any) { super(humanoid, applier) } public update(delta: number): void { if (this.target != null && this.autoUpdate) { this.lookAt(this.target.getWorldPosition(_v3A)) } if (this._needsUpdate) { this._needsUpdate = false this.applier.applyYawPitch(this._yaw, this._pitch) } } }
const vrmLookAt = new CustomVRMLookAt(vrm.humanoid, vrm.lookAt.applier) vrmLookAt.copy(vrm.lookAt) vrm.lookAt = vrmLookAt vrm.lookAt.target = camera vrm.update(1)
このとき、updateの実行をさせないために以下の変更を加えた時をAとします。
public update(delta: number): void { // if (this.target != null && this.autoUpdate) { // this.lookAt(this.target.getWorldPosition(_v3A)) // } // if (this._needsUpdate) { // this._needsUpdate = false // this.applier.applyYawPitch(this._yaw, this._pitch) // } }
また、updateの実行をさせないために以下の変更を加えた時をBとします。
const vrmLookAt = new CustomVRMLookAt(vrm.humanoid, vrm.lookAt.applier) vrmLookAt.copy(vrm.lookAt) vrm.lookAt = vrmLookAt vrm.lookAt.target = camera // vrm.update(1)
AとBはどちらもupdateの内容を実行させない変更ですが、挙動が異なります。
どういった原因が考えられますか。
AとBの変更は、どちらもupdate
メソッドを実行しないため、update
メソッドの内容が実行されないという点では同じです。しかし、挙動が異なる原因は、update
メソッド内のコードが異なるためです。
Aの場合、update
メソッド内では、this.target
が存在し、かつthis.autoUpdate
がtrue
の場合にのみ、lookAt
メソッドとapplier.applyYawPitch
メソッドが呼ばれます。
一方、Bの場合、update
メソッドが全てコメントアウトされているため、lookAt
メソッドとapplier.applyYawPitch
メソッドは全く実行されません。
結果的に、AではlookAt
メソッドとapplier.applyYawPitch
メソッドは呼ばれないが、Bでは全く実行されないため、挙動が異なるということになります。
最終的な実行結果はAとBで同じになるはずですが、そうなりません。
申し訳ありません、誤解の解消ができていなかったようです。
実行結果が異なるのは、update
メソッドが実行されないためではなく、vrm.update(1)
の呼び出しの有無によるものです。つまり、AでもBでもvrm.update(1)
を実行しない場合には、update
メソッドが呼び出されないため、処理内容による影響がありません。
もしもAとBで実行結果が異なるならば、それはvrm.update(1)
が影響を与えている可能性があります。vrm.update(1)
によって、vrm
オブジェクトやその内部の状態が変化することで、結果が異なることがあります。
この場合、vrm.update(1)
を実行した際に、update
メソッド内の処理が実行されて、その結果が異なる可能性があります。具体的にどのような変化が起きるかは、update
メソッド内のコードやvrm
オブジェクトの実装に依存します。
したがって、実行結果がAとBで異なる場合、vrm.update(1)
の実行が原因であると考えられます。vrm.update(1)
の挙動を確認して、その結果を分析することで、原因を特定できるかもしれません。
JSで継承元クラスのメソッドをオーバーライドしたとき、オーバーライドされたメソッドの処理が実行されることはありますか。
はい、JavaScriptにおいて継承元クラスのメソッドをオーバーライドすると、オーバーライドされたメソッドの処理が実行されるようになります。
継承元クラスのメソッドをオーバーライドすると、サブクラスで同じ名前のメソッドを定義することができます。そして、そのメソッドが呼び出された場合には、サブクラスで定義されたメソッドが実行されます。
ただし、サブクラスでオーバーライドしたメソッド内で、継承元クラスの同じ名前のメソッドを呼び出したい場合は、「super」キーワードを使用することができます。これにより、オーバーライドされたメソッドと継承元クラスのメソッドの両方の処理を実行することができます。
具体的なコード例を示します。
class Parent { method() { console.log("Parent's method"); } } class Child extends Parent { method() { super.method(); // 継承元クラスのメソッドを呼び出し console.log("Child's method"); } } const obj = new Child(); obj.method(); // 出力: "Parent's method" と "Child's method"
上記の例では、Child
クラスでmethod
メソッドをオーバーライドしています。そのため、Child
クラスのmethod
メソッドが呼び出された際には、継承元クラスのParent
クラスのmethod
メソッドと、Child
クラスのmethod
メソッドの両方の処理が実行されます。
寝ぼけていた。。。
updateは異なるクラスのメソッドだった。