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();
_
著者がDrive
を使用してFly
およびprototype
メソッドを追加し、Car
クラス内で_this.Drive
_メソッドとして宣言しなかった理由SuperCar
クラスの_this.Fly
_として?
なぜ_SuperCar.prototype.constructor
_をSuperCar
に戻す必要があるのですか? constructor
が設定されている場合、prototype
プロパティはオーバーライドされますか?私はこの行をコメントアウトしましたが、何も変わりませんでした。
SuperCar
コンストラクターでCar.call(this, name);
を呼び出すのはなぜですか? Car
のプロパティとメソッドが「継承」されない
_var myCar = new Car("Car");
_
2つのブロックは、最初の例ではDrive()
が1回だけ存在し、2番目のアプローチではDrive()
がインスタンスごとに存在するという点で異なります(new Car()
drive()
が再度作成されます)。または、最初の関数はプロトタイプを使用して関数を保存し、2番目の関数はコンストラクターを使用するという。関数のルックアップはコンストラクターであり、プロトタイプです。したがって、Drive()
のルックアップでは、コンストラクター内にあるかプロトタイプ内にあるかに関係なく検索されます。通常、必要なのは型ごとに1回だけなので、プロトタイプの使用はより効率的です。
JavaScriptのnew
呼び出しは、プロトタイプのコンストラクターを自動的に設定します。プロトタイプを上書きする場合は、コンストラクターを手動で設定する必要があります。
Javascriptの継承には、super
のようなものはありません。したがって、サブクラスがある場合、スーパーコンストラクターを呼び出す唯一の機会はその名前です。
Norbert Hartl's answer に追加するには、SuperCar.prototype.constructorは必要ありませんが、一部の人々はオブジェクト(この場合はSuperCarオブジェクト)。
最初の例から、Car.call(this、name)はSuperCarコンストラクター関数にあります。これを行うとき:
_var mySuperCar = new SuperCar("SuperCar");
_
これがJavaScriptの機能です。
JavaScriptがCarを呼び出していないことに注意してください。プロトタイプはそのままで、SuperCar用に自分で設定していないプロパティやメソッドはすべてCarで検索されます。時々これは良いです、例えばSuperCarにはDriveメソッドはありませんが、Carのメソッドを共有できるため、すべてのSuperCarは同じDriveメソッドを使用します。他の場合は、各スーパーカーが独自の名前を持っているなど、共有したくない場合があります。それでは、各スーパーカーの名前をそれ自身の名前に設定するにはどうすればよいのでしょうか? SuperCarコンストラクター関数内でthis.Nameを設定できます。
_function SuperCar(name){
this.Name = name;
}
_
これは機能しますが、しばらくお待ちください。 Carコンストラクターでまったく同じことをしませんでしたか?繰り返したくありません。 Carはすでに名前を設定しているので、名前を付けましょう。
_function SuperCar(name){
this = Car(name);
}
_
おっと、特別なthis
オブジェクト参照を変更する必要はありません。 4つのステップを覚えていますか? JavaScriptが提供するオブジェクトにつかまってください。SuperCarオブジェクトとCarの間の貴重な内部プロトタイプリンクを保持する唯一の方法だからです。では、どうすればNameを設定できますか。自分自身を繰り返したり、新しいSuperCarオブジェクトJavaScriptを捨てたりせずに、JavaScriptが準備に多大な労力を費やしたのでしょうか。
二つのこと。 1つ:this
の意味は柔軟です。 2:車は機能です。 Carを呼び出すには、純粋で新鮮なインスタンス化されたオブジェクトではなく、たとえばSuperCarオブジェクトを使用します。これで最終的な解決策が得られます。これは、質問の最初の例の一部です。
_function SuperCar(name){
Car.call(this, name);
}
_
関数として、Carは関数の callメソッド で呼び出すことができます。これは、Car内のthis
の意味をSuperCarに変更します構築中のインスタンス。プレスト!各SuperCarは、独自のNameプロパティを取得するようになりました。
最後に、SuperCarコンストラクターのCar.call(this, name)
は、それぞれの新しいSuperCarオブジェクトに固有のNameプロパティを与えますが、既にCarにあるコードを複製することはありません。
プロトタイプは一度理解すれば怖くはありませんが、古典的なクラス/継承OOPモデルではありません。私は に関する記事を書きました。 JavaScriptのプロトタイプコンセプト JavaScriptを使用するゲームエンジン用に記述されていますが、Firefoxで使用されるJavaScriptエンジンと同じであるため、すべて関連性があります。
ノーバート、あなたはあなたの最初の例がダグラス・クロックフォードが疑似古典的継承と呼ぶものとほとんど同じであることに注意すべきです。これについて注意すべきこと:
最後に、ここで機能するTDD JavaScript継承コードの例をいくつか紹介します。 TDD JavaScript継承コードとエッセイ 改善を望んでいるので、フィードバックをもらいたいですそれをオープンソースにしてください。目標は、古典的なプログラマーがJavaScriptをすばやく習得できるようにすることと、Crockfordの本とZakasの本の両方を学習することです。
function abc() {
}
関数abc用に作成されたプロトタイプメソッドとプロパティ
abc.prototype.testProperty = 'Hi, I am prototype property';
abc.prototype.testMethod = function() {
alert('Hi i am prototype method')
}
関数abcの新しいインスタンスを作成する
var objx = new abc();
console.log(objx.testProperty); // will display Hi, I am prototype property
objx.testMethod();// alert Hi i am prototype method
var objy = new abc();
console.log(objy.testProperty); //will display Hi, I am prototype property
objy.testProperty = Hi, I am over-ridden prototype property
console.log(objy.testProperty); //will display Hi, I am over-ridden prototype property
http://astutejs.blogspot.in/2015/10/javascript-prototype-is-easy.html
100%確かではありませんが、違いは、2番目の例ではCarクラスの内容を単にSuperCarオブジェクトに複製し、最初の例ではSuperCarプロトタイプをCarクラスにリンクすることです。 CarクラスはSuperCarクラスにも影響します。