1. ホーム
  2. javascript

[解決済み] JavaScriptのプロトタイプ継承を理解する

2022-04-22 16:13:39

質問

私はJavaScriptのOOPの初心者です。以下のコードブロックの違いを説明してもらえますか?テストしたところ、どちらのブロックも動作しました。ベストプラクティスは何ですか、そしてなぜですか?

最初のブロック

function Car(name){
    this.Name = name;
}

Car.prototype.Drive = function(){
    console.log("My name is " + this.Name + " and I'm driving.");
}

SuperCar.prototype = new Car();
SuperCar.prototype.constructor = SuperCar;

function SuperCar(name){
    Car.call(this, name);
}

SuperCar.prototype.Fly = function(){
    console.log("My name is " + this.Name + " and I'm flying!");
}

var myCar = new Car("Car");
myCar.Drive();

var mySuperCar = new SuperCar("SuperCar");
mySuperCar.Drive();
mySuperCar.Fly();

2つ目のブロック

function Car(name){
    this.Name = name;
    this.Drive = function(){ 
        console.log("My name is " + this.Name + " and I'm driving.");
    }
}

SuperCar.prototype = new Car();

function SuperCar(name){
    Car.call(this, name);
    this.Fly = function(){
        console.log("My name is " + this.Name + " and I'm flying!");
    }
}

var myCar = new Car("Car");
myCar.Drive();

var mySuperCar = new SuperCar("SuperCar");
mySuperCar.Drive();
mySuperCar.Fly();

なぜ、作者は DriveFly メソッドを使用しています。 prototype として宣言しておらず this.Drive メソッドの内部で Car クラスと this.Fly の中で SuperCar クラスですか?

なぜ SuperCar.prototype.constructor に戻す必要があります。 SuperCar ? また constructor プロパティがオーバーライドされたとき prototype が設定されているのでしょうか?この行をコメントアウトしても何も変わりません。

なぜ Car.call(this, name); の中で SuperCar コンストラクタを使用しますか?のプロパティやメソッドは Car を実行すると、「継承」されます。

var myCar = new Car("Car");

解決方法は?

この2つのブロックは、最初の例では、次のように異なっています。 Drive() は一度しか存在しないのに対し、2番目のアプローチでは Drive() はインスタンスごとに存在する(毎回 new Car() 関数 drive() が再び作成されます)。あるいは、最初の関数はプロトタイプを使用し、2番目の関数はコンストラクタを使用すると言うこともできます。関数のルックアップはコンストラクタ、プロトタイプの順で行われます。ですから Drive() の場合、コンストラクタにあるのかプロトタイプにあるのかに関係なく見つかります。通常、関数は1つの型に1回しか必要ないので、プロトタイプを使用する方が効率的です。

その new を呼び出すと、自動的にプロトタイプにコンストラクタが設定されます。プロトタイプを上書きしている場合は、コンストラクタを手動で設定する必要があります。

javascriptの継承には、以下のようなものはありません。 super . そのため、サブクラスがある場合、スーパーコンストラクタを呼び出すには、その名前を使うしかありません。