JS がオブジェクト指向であることはわかっています。オブジェクト指向について語るとき、クラスの概念が避けて通れません。一般に、C# や Java などの厳密に型指定された言語には、クラスを定義するための固定構文があります。 JS との違いは、さまざまなメソッドを使用して独自のクラスやオブジェクトを実装できることです。一般的な実装メソッドはいくつかあります。
1. ファクトリ メソッド
ファクトリ メソッドは、特定のオブジェクト タイプを返すファクトリ関数の作成を指します。サンプル コードは次のとおりです。 🎜>
この方法でファクトリ関数が呼び出されるたびに、新しいオブジェクトが作成されます。しかし、問題は、新しいオブジェクトが生成されるたびに、新しい関数 showColor を作成する必要があることです。これにより、各オブジェクトが独自のバージョンの showColor を持ちます。実際、この問題を解決するために、開発者はメソッドを使用します。オブジェクトのオブジェクトはファクトリ関数の外で定義されており、次のようにオブジェクトにはこの関数を指すポインタが与えられます
この方法では、オブジェクトごとに独自の showColor 関数を作成する必要はなく、この関数へのポインターを作成するだけで問題は解決します。機能的には同じですが、この関数はオブジェクト メソッドと似ていません。そこで、コンストラクターメソッドが導入されました。
2. コンストラクター メソッド
このメソッドは、次のようにみなすことができます。新しいオブジェクトを作成するための基礎。ここでは、空のコンストラクターを使用してクラス名を設定します。次に、すべてのメソッドとプロパティをプロトタイプ属性に直接割り当てます。次のように:
Car.prototype.drivers=new Array( "マイク", "スー");
Car.prototype.showColor=function()
{
alert(this.color);
}
プロトタイプ メソッドは値を直接割り当てることしかできず、コンストラクターにパラメーターを渡してプロパティの値を初期化することはできません。この方法を使用すると、気づいたかどうかわかりませんが、2 つの問題に遭遇します。最初の問題は、このアプローチでは、プロパティのデフォルト値を変更する前に各オブジェクトを作成する必要があることです。各オブジェクトを作成するのではなく、必要な属性値を直接持つことはできません。これは迷惑です。 2 番目の問題は、属性がオブジェクトを参照する場合です。関数の共有には問題ありませんが、オブジェクトの共有には問題があります。通常、各インスタンスは独自のオブジェクトを実装するためです。
は次のとおりです:
var oCar1= new Car();
var oCar2=new Car();
oCar1.drivers.push("Matt");
alert(oCar1.drivers);//出力 "マイク、 Sue,Matt"
alert(oCar2.drivers);//出力 "Mike, Sue, Matt"
したがって、drivers 属性はオブジェクトへの単なるポインタであるため、実際にはすべてのインスタンスが同じオブジェクトを共有します。このような問題を解決するため、以下のようなコンストラクタとプロトタイプを併用する方法を導入しました。
4. コンストラクターとプロトタイプの混合アプローチ
このアプローチの考え方は、オブジェクトのすべての非関数プロパティ (通常のプロパティとプロパティを含む) を定義するためにコンストラクターを使用することです。オブジェクトを指します)、オブジェクトの関数属性(メソッド)をプロトタイプ形式で定義します。その結果、すべての関数は 1 回だけ作成され、各オブジェクトは独自のオブジェクト プロパティ インスタンスを持ちます。サンプル コードは次のとおりです。
関数Car(sColor,iDoors,iMpg )
{
this.color=sColor;
this.doors=iDoors;
this.mpg=iMpg;
this.drivers=new Array("マイク","スー") ;
}
Car.prototype.showColor=function()
{
alert(this.color);
}
var oCar1=new Car ("赤",4, 23);
var oCar2=new Car("青",3,25);
oCar1.drivers.push("Matt");
alert(oCar1.drivers );//出力 "Mike ,Sue,Matt"
alert(oCar2.drivers);//出力 "Mike,Sue"
コード例からわかるように、このメソッドは前の方法の 2 つの問題を同時に解決します。ただし、開発者の中には、このアプローチが完璧ではないと感じている人もいます。
5. 動的プロトタイプ メソッド
ほとんどのオブジェクト指向言語には、視覚的にカプセル化されたプロパティとメソッドがあることがわかっています。ただし、上記メソッドの showColor メソッドはクラスの外で定義されています。したがって、彼らは動的なプロトタイピングのアプローチを設計しました。このアプローチの基本的な考え方は、ハイブリッド コンストラクター/プロトタイプ アプローチと同じですが、唯一の違いはオブジェクト メソッドの場所です。以下に示すように:
function Car(sColor ,iDoors,iMpg )
{
this.color=sColor;
this.doors=iDoors;
this.mpg=iMpg;
this.drivers=new Array("マイク", "スー") ;
if(typeof Car._initialized=="未定義")
{
Car.prototype.showColor=function()
{
alert(this.color);
}
}
Car._initialized=true;
}
このようにして、Car.prototype.showColor は 1 回だけ作成されます。この依存関係により、このコードは他の言語のクラス定義に似たものになります。
6. 混合ファクトリー法
この方法は通常、前の方法の回避策です。その目的は、別の種類のオブジェクトの新しいインスタンスを返すだけの偽のコンストラクターを作成することです。
function createCar()
{
var oTempCar=new Object;
oTempCar.color=“red”;
oTempCar.doors=4;
oTempCar.mpg=23;
oTempCar.showColor=function()
{
alert(this.color);
};
return oTempCar;
}
var car=new Car();
車の中だから() コンストラクター new 演算子は内部で呼び出されるため、2 番目の new 演算子は自動的に無視されます。コンストラクター内で作成されたオブジェクトは変数 var に戻されます。このアプローチには、オブジェクト メソッドの内部管理に関する従来のアプローチと同じ問題があります。したがって、どうしても必要な場合を除き、この方法の使用を避けることを強くお勧めします。