JSにおけるクラスまたはオブジェクトの定義説明


私達は知っています。JSは対象者向けです。対象に向かうとなると、類の概念に関わることは避けられない。一般的にはc铉やjavaなどの強いタイプの言語には固定的な定義類の文法があります。JSの違いは、それぞれの方法を使って自分の種類と対象を実現することです。一般的な実装には、以下のような方法があります。1.工場方式工場方式とは、特定の対象の種類に戻る工場関数を作成することを指します。例コードは以下の通りです。

function createCar(sColor,iDoors,iMpg)
{
   var oTempCar=new Object;
   oTempCar.color=sColor;
   oTempCar.doors=iDoors;
   oTempCar.mpg=iMpg;
   oTempCar.showColor=function()
   {
        alert(this.color);
   }
   return oTempCar;
}
var oCar1=createCar("red",4,23);
var oCar2=createCar("blue",3,25);
oCar1.showColor();
oCar2.showColor();
のように、その工場関数を呼び出すたびに、新しいオブジェクトを作成します。しかし問題は、新しいオブジェクトを生成するたびに、新しい関数showColorを作成します。これにより、各オブジェクトに自分のshowColorバージョンがあります。実際には、すべてのオブジェクトが同じ関数を共有します。この問題を解決するために、開発者は工場の関数の外で対象を定義して、オブジェクトにポインタを与えてこの関数を指します。このように

function showColor()
{
   alert(this.color);
}
function createCar(sColor,iDoors,iMpg)
{
   var oTempCar=new Object;
   oTempCar.color=sColor;
   oTempCar.doors=iDoors;
   oTempCar.mpg=iMpg;
   oTempCar.showColor=showColor;
   return oTempCar;
}
var oCar1=createCar("red",4,23);
var oCar2=createCar("blue",3,25);
oCar1.showColor();
oCar2.showColor();
のように、各オブジェクトのために自分のshowColor関数を作成する必要はなく、この関数を指すポインタを作成します。これは機能的に問題を解決しましたが、この関数は対象とは異なります。そこで,構造関数の方式を引き出す。2.コンストラクタ方式のコンストラクタは工場関数と似ています。例コードは以下の通りです。new演算子を使ってコンストラクタを呼び出すときは、最初の行のコードを実行する前にオブジェクトを作成します。このオブジェクトにはthisを使ってのみアクセスできます。しかし、これはどのような問題がありますか?明らかに、各オブジェクトもショーColor関数バージョンを作成します。この問題を解決するために、次のプロトタイプを引き出しました。3.プロトタイプは、オブジェクトのプロトタイプ属性を利用して、新しいオブジェクトを作成するために依存するプロトタイプと見なします。ここでは、空の構造関数でクラス名を設定します。そして、すべての方法と属性を直接prototype属性に与えます。

function Car(sColor,iDoors,iMpg)
{
   this.color=sColor;
   this.doors=iDoors;
   this.mpg=iMpg;
   this.showColor=function()
   {
      alert(this.color);
   }
}
var oCar1=new Car("red",4,23);
var oCar2=new Car("blue",3,25);
プロトタイプ方式は直接的に値しか与えられず、構造関数にパラメータ初期化属性の値を伝達することによっては初期化できない。このような方式を使う時、2つの問題に出会うことができて、みんなが気づかないことを知りません。第一の問題は、このようにして各オブジェクトを作成してから属性のデフォルト値を変更することです。各オブジェクトを作成する際には、直接に自分の必要な属性値を持つことはできません。この点はとても嫌です。二つ目の問題は属性が対象の場合です。関数共有には問題はありませんが、オブジェクト共有に問題があります。なぜなら、それぞれのインスタンスは通常、自分のオブジェクトを実現するからです。以下のように:

function Car()
{}
Car.prototype.color="red";
Car.prototype.doors=4;
Car.prototype.mpg=23;
Car.prototype.drivers=new Array("Mike","Sue");
Car.prototype.showColor=function()
{
   alert(this.color);
}
、したがって、drivers属性はオブジェクトのポインタだけを指すので、全ての例は事実上同じオブジェクトを共有する。これらの問題のために,構造関数とプロトタイプ方式の共同使用を引き出した。4.混合の構造関数/プロトタイプのこの方式の思想は、オブジェクトの関数属性を構成関数で定義し、オブジェクトの関数属性をプロトタイプで定義します。その結果、すべての関数は一回だけ作成され、各オブジェクトは自分のオブジェクト属性インスタンスを持っています。例示的なコードは以下の通りである。

var oCar1=new Car();
var oCar2=new Car();
oCar1.drivers.push("Matt");
alert(oCar1.drivers);// "Mike,Sue,Matt"
alert(oCar2.drivers);// "Mike,Sue,Matt"
は例示的なコードによって分かり、この方法は前の方法の2つの問題を同時に解決する。しかし、このような方式を採用しても、完璧ではないと感じる開発者がいます。5.動的プロトタイプ方式は、対象言語の多くが属性と方法を視覚的にカプセル化していることを知る。上記の方法のshow Color方法は種類の外に定義されています。したがって,彼らは動的プロトタイプ法を設計した。この方式の基本思想と混合の構造関数/プロトタイプ方式は同じで、唯一の違いはオブジェクト法の位置にある。

function Car(sColor,iDoors,iMpg)
{
   this.color=sColor;
   this.doors=iDoors;
   this.mpg=iMpg;
   this.drivers=new Array("Mike","Sue");
}
Car.prototype.showColor=function()
{
   alert(this.color);
}
var oCar1=new Car("red",4,23);
var oCar2=new Car("blue",3,25);
oCar1.drivers.push("Matt");
alert(oCar1.drivers);// "Mike,Sue,Matt"
alert(oCar2.drivers);// "Mike,Sue"
このような方式は、Card.prototype.showColorが一回だけ作成されます。このように依存して、このコードは他の言語のクラス定義に似ています。6.混合工場方式という方式は、通常は前の方式の融通がきかない方法である。その目的は、他のオブジェクトの新しいインスタンスだけを返すために擬似構造関数を作成することです。

function Car(sColor,iDoors,iMpg)
{
   this.color=sColor;
   this.doors=iDoors;
   this.mpg=iMpg;
   this.drivers=new Array("Mike","Sue");
   if(typeof Car._initialized=="undefined")
  {
     Car.prototype.showColor=function()
     {
        alert(this.color);
     }
  }
  Car._initialized=true;
}
は、カール()構造関数の内部でnew演算子を呼び出したので、第二のnew演算子を自動的に無視します。コンストラクタ内部で作成されたオブジェクトは変数varに転送されます。この方式は対象法の内部管理において経典方式と同じ問題を持っている。だから強烈な提案:万やむを得ない限り、やはりこのような方式を使うことを免れます。