JavaScript のクラス継承については、Ruan Yifeng のブログ「JavaScript 継承メカニズムの設計アイデア」を参照してください。非常に詳しく説明されています。
1. JavaScript でインスタンス化するときに発生した問題:
以下では、「JavaScript 高度なプログラミング」の例を使用して説明します。車のオブジェクトが定義されている場合、それは Object クラスのインスタンスです。次のようにします:
var oCar=new Object () ;
oCar.color = "red";
oCar.mpg = 23;
oCar.showColor = function () {
alert(this. color) ;
};
このようなインスタンスが必要です。
var oCar2 = new Object();
oCar2.color = "blue";
oCar2.doors = 5;
oCar2.mpg = 25;
oCar2.showColor = function () {
alert(this.color);
この方法で発生した問題それは、各オブジェクトのフィールドとメソッドを再定義する必要があるということです。とても面倒です。
2. クラス定義 - ファクトリ メソッドの実装:
上記の例をラップし、関数の戻り値を使用して記事を作成します:
コードをコピーします
alert(this.color);
return oTempCar;
メソッドの呼び出し:
var oCar1 = createCar();
var oCar2 = createCar(); > この方法をファクトリーメソッドといいます。ファクトリーメソッドの方がはるかに簡単なようです。少なくとも、オブジェクトを作成するときにそれほど多くの行を必要としなくなりました。各属性 (color、doors、mpg) の値は固定されているため、パラメータ渡しを使用して再度変換する必要があります:
Copy code
コードは次のとおりです。
function createCar(sColor, iDoors, iMpg) {
var oTempCar = new Object();
oTempCar.color = sColor; >oTempCar.doors = iDoors;
oTempCar.mpg = iMpg;
alert(this.color) return oTempCar; ; } var oCar1 = createCar("red", 4, 23); var oCar2 = createCar("red", 4, 23); showColor();
oCar2.showColor();
これで目的は達成できそうです。実装も非常に簡単で呼び出しも非常に便利です。しかし、あまり良くない点が 2 つあります。
1. セマンティックの観点から見ると、オブジェクトの作成時に new 演算子は使用されません。これはあまり形式的ではないようです (通常、オブジェクトの作成)。新しい演算子) ) を使用して実装されます。
2. オブジェクト指向の特性であるカプセル化に準拠していません。この例では、oCar1 と oCar2 の両方に独自の showColor メソッドがあり、showColor 実装も独自のものです。しかし実際には、それらは同じ機能を共有しています。
関数ポインタを使用して、共有関数のこの問題を解決する方法もあります。 createCar 関数の外側に showColor 関数を作成し、oTempCar の showColor メソッドがこの showColor 関数を指します:
コードをコピー
コードは次のとおりです。
function showColor() {
alert(this.color);
}
function createCar(sColor, iDoors, iMpg) {
var oTempCar = new Object();
oTempCar.color = sColor;
oTempCar.mpg = iMpg;
oTempCar.showColor;
これにより、関数を繰り返し作成する問題は解決されますが、showColor 関数がオブジェクト メソッドのように見えなくなります。
3. クラス定義 -- コンストラクター メソッドの実装:
コードをコピーします
コードは次のとおりです。 >
function Car(sColor, iDoors, iMpg) {
//コンストラクターの形式で、オブジェクトごとに独立したプロパティと関数が生成されます
this.color = sColor
this.doors = iDoors;
this.mpg = iMpg;
alert(this.color);
var oCar1 = 新しい Car("red", 4, 23);
var oCar2 = new Car("red", 4, 23); .showColor();
Car クラスでは、このポインターは Car のインスタンスを表すため、値を返す必要はありません。コンストラクター メソッドは、ファクトリ メソッドと同様にクラスの定義を実装しますが、インスタンスごとに個別のメソッドも作成します。この問題を解決するためにポインターを使用するファクトリ関数のような関数の外に関数を作成することもできますが、それを行うことは意味的に意味がありません。
4. クラス定義 - プロトタイプの実装:
オブジェクトのプロトタイプ属性を使用し、それを新しいオブジェクトの作成に依存するプロトタイプとみなします。空のコンストラクターを使用してクラス名を設定します。次に、すべてのプロパティとメソッドがプロトタイプ属性に直接割り当てられます。
コードをコピーします
Car.prototype.doors = 4;
Car.prototype.mpg = 23; {
alert(this.color);
};
var oCar1 = new Car();
var oCar2 = new Car(); ;// ここでの出力 true には 2 つの問題があります:
1. コンストラクターにはパラメーターがありません。プロトタイプを使用する場合、関数のパラメーターにパラメーターを渡してプロパティ値を初期化することはできません。
2. 複数のインスタンスがある場合、1 つのインスタンスのプロパティを変更すると、もう 1 つのインスタンスのプロパティに影響します。
テストコード:
コードをコピー
コードは次のとおりです:
alert(oCar1.color); // 出力 黒
この質問の解決策になります。それがコンストラクター/プロトタイプ混合メソッド
5. クラス実装 - コンストラクター/プロトタイプ混合メソッド
この実装メソッドは各クラスのインスタンス間で共有されます プロパティまたはメソッドはプロトタイプ チェーンに実装する必要があります、実装する必要のないプロパティやメソッドはコンストラクターに実装する必要があります。このクラスの実装は、最も広く使用されているメソッドです。
コードをコピー
コードは次のとおりです:
var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 24);
oCar1.drivers.push("Matt");
alert(oCar1.drivers); oCar2.drivers ); 6. クラス定義 - 動的プロトタイプの実装
混合コンストラクター/プロトタイプ メソッドと比較して、このメソッドは使いやすいプログラミング スタイルを提供します (混合コンストラクターでは /プロトタイプ メソッドでは、 showColor メソッドの定義は、コンストラクターのメソッド本体内ではなく、メソッド本体の外部で実装されます)。このクラスを定義するにはさまざまな方法があります。
コードをコピー
コードは次のとおりです:
function Car(sColor, iDoors, iMpg) {
this.color = sColor;
this.mpg = iMpg;
7. クラス定義 - 混合ファクトリ実装
コードをコピーします
コードは次のとおりです。
function Car() {
var oTempCar = new Object();
oTempCar.color = "red"; ;
oTempCar.mpg = 23;
oTempCar.showColor = function () {
return