JavaScript 12:JavaScriptは対象に向かう作成対象に基づく(二)


四原型方式
       私たちが作成した各関数にはプロトタイプの属性があります.この属性はオブジェクトです.用途は特定のタイプによって使用できます.
のすべてのインスタンスで共有される属性と方法.プロトタイプは、バーを介して構成関数で作成されたそのオブジェクトのプロトタイプオブジェクトを理解することができます.使います
プロトタイプを使う利点は、すべてのオブジェクトインスタンスにその中に含まれる属性と方法を共有させることです.つまり、構造関数でオブジェクト情報を定義する必要はなく、
これらの情報を直接原型に追加します.
       プロトタイプ方式は、オブジェクトのプロトタイプ属性を利用して、新しいオブジェクトを作成するために依存するプロトタイプと見なすことができます.ここで、まず空のコンストラクタを使って設定します.
関数名そして、すべての属性と方法は直接プロポーチ属性を与えられます.前の例を書き直しました.コードは以下の通りです.
function Car() { };
//            prototype  
Car.prototype.color = "blue";
Car.prototype.doors = 4;
Car.prototype.mpg = 25;
Car.prototype.showColor = function() {
     return this.color;
};
var Car1 = new Car();
var Car2 = new Car();
document.write(Car1.showColor()+"<br/>");//  :blue
document.write(Car2.showColor());//  :blue
      このコードでは、まずコンストラクタCar()を定義します.コードはありません.次の何行かのコードは、カールさんへの prototype属性追加
属性を指定します.new Car()を呼び出した時、プロトタイプのすべての属性は直ちに作成する対象に与えられます.
置くのはショーColor()の関数を指す指針です.意味的には、すべての属性は一つの対象に見えるので、前の工場方式を解決しました.
とコンストラクタ方式に存在する問題.
       さらに、このようにして、所定の変数が指すオブジェクトの種類をinstance of演算子でチェックすることもできます.
<span style="font-size:18px;">document.write(Car1 instanceof Car);	//  :true</span>
      モデル方式はよさそうな解決策です.残念なことに、それは意のままにならないです.まず,この構造関数にはパラメータがない.原型を使う
構造関数にパラメータを送ることで属性の値を初期化できません. 「blue」、doors属性は全部同じです.
4,mpg属性は全部25に等しい.これは、オブジェクトが作成された後に属性のデフォルト値が変更されることを意味します.本当の質問
属性がオブジェクトを指すのであって、関数ではない場合に問題が現れます.関数共有は問題にならないが、オブジェクトは複数のインスタンスによって共有されない.次のことを考えてください
例:
function Car() { };//         ,        
Car.prototype.color = "blue";
Car.prototype.doors = 4;
Car.prototype.mpg = 25;
Car.prototype.drivers = new Array("Mike","John");
Car.prototype.showColor = function() {
      return this.color;
};
var Car1 = new Car();
var Car2 = new Car();
Car1.drivers.push("Bill");
document.write(Car1.drivers+"<br/>");//  :Mike,John,Bill
document.write(Car2.drivers);//   :Mike,John,Bill
       上のコードでは、属性driversは、Arayオブジェクトを指すポインタであり、この配列には「Mike」と「John」という2つの名前が含まれています.によって driversは参照です
この値は、Carの二つの例が同じ配列を指しています.これは、Cal 1.driversに値「Bill」を追加することを意味します. Card.driversにも見られます.この二つを出力します
いずれのポインタも、文字列「マイク、ジョン、ビル」を表示します.相手を作る時にこんなに多くの問題がありますから、間違いなく考えます.
合理的にオブジェクトを作成する方法は?答えはあります.コンストラクションとプロトタイプを共同で使う必要があります.
       五混合の構造関数/プロトタイプ方式(推奨使用)
       コンストラクタ方式とプロトタイプ方式を混合すると、他のプログラムで言語を設計するようにオブジェクトを作成できます.このような概念は非常に簡単で,すなわち構造状を用いている.
数は、オブジェクトの非関数属性をすべて定義し、オブジェクトの関数属性をプロトタイプで定義します.その結果、すべての関数は一回だけ作成されます.
オブジェクトは自分のオブジェクト属性のインスタンスを持っています.前の例を書き直しました.コードは以下の通りです.
function Car(Color,Doors,Mpg) {
  this.color = Color;
  this.doors = Doors;
  this.mpg = Mpg;
  this.drivers = new Array("Mike","John");
};
Car.prototype.showColor = function() {
         return this.color;
};
var Car1 = new Car("red",4,23);
var Car2 = new Car("blue",3,25);
Car1.drivers.push("Bill");
document.write(Car1.drivers+"<br/>");//  :Mike,John,Bill
documnet.write(Car2.drivers);//  :Mike,John
       今はもっと一般的なオブジェクトを作成します.すべての非関数属性は構造関数で作成されます.構造関数のパラメータで属性を与えることができるという意味です.
デフォルトです.showColor関数の一例だけを作成しますので、メモリの無駄はありません.また、カード1のdrivers配列に「Bill」値を追加し、
Card 2の配列に影響がないので、これらの配列の値を出力する時に、Car 1.driversが表示するのは 「Mike,John,Bill」と,Card.driversが示した
マイク、ジョンです.原型方式を使っていますので、まだ利用できます. instance of演算子は、オブジェクトの種類を判断します.
       この方式はECMAScriptが採用する主要な方式で、他の方式の特性を持っていますが、彼らの副作用はありません.しかし、一部の開発者はまだ感じています.
この方法は完璧ではないです.
      六ダイナミックプロトタイプ方式
      他の言語を使い慣れた開発者にとっては、ハイブリッドの構造関数/プロトタイプ方式を使うのはあまり調和がとれていません.結局、クラスを定義する時、大多数は
対象言語に向かって属性と方法を視覚的にパッケージ化した.以下のJavaクラスを考慮してください.
class Car {
  public String color = "blue";
  public int doors = 4;
  public int mpg = 25;
  public Car(String color, int doors, int mpg) {
      this.color = color;
      this.doors = doors;
      this.mpg = mpg;
  }
  public void showColor() {
      System.out.println(color);
  }
}
        Javaはカール類のすべての属性と方法をうまく包装しています.このコードを見て、どのような機能を実現するかが分かります.対象を定義しています.
メッセージ.混合の構造関数/プロトタイプ方式を批判する人は,構造関数の内部で属性を探し,その外部で方法を探すやり方が論理的ではないと考えている.だから彼は
動的プロトタイプ法を設計して、より友好的なコードスタイルを提供します.
       動的プロトタイプ法の基本的な考え方は,混合のコンストラクタ/プロトタイプと同じで,すなわちコンストラクタ内で非関数的な属性を定義し,関数的な属性は利用される.
プロトタイプの定義.唯一の違いは対象方法を付与する位置です.次はダイナミックプロトタイプの方法で書き換えたカールです.
function Car(Color,Doors,Mpg) {
  this.color = Color;
  this.doors = Doors;
  this.mpg = Mpg;
  this.drivers = new Array("Mike","John");
  //  Car    _initialized undefined,      Car       
  if (typeof Car._initialized == "undefined") {
         Car.prototype.showColor = function() {
                return this.color;
         };	
         Car._initialized = true; //   true,    prototype    
  }
}
var Car1 = new Car("red",4,23);//    Car  
var Car2 = new Car("blue",3,25);
Car1.drivers.push("Bill");// Car1     drivers        
document.write(Car1.drivers+"<br/>");//  :Mike,John,Bill
document.write(Car2.drivers);//  :Mike,John
       typeof Car._.をチェックするまでinitializeが「undefined」に等しいかどうかは、このコンストラクタは変更されていません.この行のコードはダイナミックプロトタイプの方法です.
の中で一番重要な部分です.この値が定義されていない場合、構造関数はプロトタイプでオブジェクトを定義する方法を続けます. カール.initializedは
trueこの値が定義されている場合(その値がtrueの場合、typeofの値がBoolean)は、この方法を作成しません.簡単に言えば、この方法は使います.
マークは原型に何らかの方法が与えられているかどうかを判断します.この方法は一回だけ作成して与えられます.伝統的なOOP開発者は喜びます.
このコードは他の言語のクラス定義のように見えます.
       私たちはどのような方式を採用すべきですか?
       前に述べたように、現在最も広く使われているのは混合の構造関数/プロトタイプ方式である.また、ダイナミックプロトタイプも流行しており、機能的にも構造的にも
数/原型方式は等価です.この2つの方法のいずれかを採用することができます.ただし、古典的な構造関数やプロトタイプを単独で使用しないでください.
コード導入問題.つまりJSは対象向けのクライアントスクリプト言語に基づいています.私たちは対象技術を学ぶ時に必要なJSと
他の厳密性の高いプログラム言語の違い.JSを正確に使用してオブジェクトを作成する合理的な方法は、構造関数とプロトタイプ方式の混合を推奨します.
オブジェクトのインスタンスを作成します.これは多くの不必要なトラブルを避けることができます.