[基礎]JavaScriptの対象(個人学習ノート)二


最初の編のいくつかの対象に対する理解があって、後の学習はもし1つの種類を定義しにくるならば、1つの対象を定義するとも言えることができて、むだ話はこんなに多くなって、引き続き学習を始めます.まず、オブジェクトを定義する方法から紹介します.
1、工場方式
    人というクラスを定義するには、その人のために属性を設定する必要があります.名前と性別があります.簡単にコードで実現できます.

  var oPerson = new Object;
  oPerson.name = "yzl";
  oPerson.sex = "female";
  oPerson.sayInfo = function(){
    alert("name : " + this.name + " ,sex :" + this.sex);
  };
    これは単純なオブジェクトを作成しただけです.複数のオブジェクトを作成するには、現在は満足できないので、導入しました.
工場関数で、改ぞう後のコード:

  function createPerson(){
    var oPerson = new Object;
    oPerson.name = "yzl";
    oPerson.sex = "female";
    oPerson.sayInfo = function(){
      alert(" name : " + this.name + " ,sex :" + this.sex);
    };
    return oPerson;
  };
  var p1 = createPerson();
  p1.sayInfo();
  p1.name = "gcm";
  p1.sex = "female";
  p1.sayInfo(); 
   ここに来て本当に一人を作成したように見えますが、不足がはっきり見えます.すべてのインスタンスの属性はオブジェクトが作成された後に具体的に修正しなければなりません.オブジェクトが作成された時に具体的な状況に応じてオブジェクトを作成することはできません.そこでコードについて修正しました.具体的には以下の通りです.

function createPerson(sName,sSex){
	var oPerson = new Object;
  oPerson.name = sName;
  oPerson.sex = sSex;
  oPerson.sayInfo = function(){
		alert("name : " + this.name + " ,sex :" + this.sex);
	};
	return oPerson;
};

var p1 = createPerson("yzl","male");
var p2 = createPerson("gcm","female");
p1.sayInfo();
p2.sayInfo(); 
    コードの修正はここまで基本的に需要を満たしています.具体的な状況によって異なる人を作成することができます.しかし.(ここまで書いたら、春の夜のマジックの依頼と同じです.許してください.)メモリを考えると、毎回createPersonはsayInfon関数を作成します.つまり、各personは自分の対応するsayInfo方法を持っていますが、方法の内容は同じですので、より良い方法を選ぶべきです.EMCAScriptはクローズドバックをサポートしているため、関数の定義をクラス外に置くことができ、後にクラスの属性をこの方法の参照に向けることができます.

  function sayInfo(){
    alert("name : " + this.name + " ,sex :" + this.sex);
  }

  function createPerson(sName,sSex){
    var oPerson = new Object;
    oPerson.name = sName;
    oPerson.sex = sSex;
    oPerson.sayInfo = sayInfo;
    return oPerson;
  }; 
  var p1 = createPerson("yzl","male");
  var p2 = createPerson("gcm","female");
  p1.sayInfo();
  p2.sayInfo(); 
   工場モデルはすでに需要を満たしています.コードを絶えず修正する過程から、工場モデルに存在する様々な問題が見られます.そこで、JAVAコードにもっと近い構造関数方式ができました.
2、コンストラクタ方式
    コンストラクタ方式は工場モードと非常に似ています.クラスを定義する時に直接にクラス名を使っていますが、パラメータの割り当てにはキーワードが使われています.
thisは、値を返す必要もありません.コードを直接見る:

  function sayInfo(){
    alert("name : " + this.name + " ,sex :" + this.sex);
  }
  function Person(sName,sSex){
    this.name = sName;
    this.sex = sSex;
    this.sayInfo = sayInfo; 
  }
  var p1 = new Person("yzl","male");
  p1.sayInfo();
    このような方式は実は工場モードのようです.何も言わないで、次の定義類の方式を続けます.
3、原型の方式
    この方式は対象の
プロトタイプ属性は、新しいオブジェクトに依存するプロトタイプとして見られます.このような方法で一つの種類を定義する方法は一般的に
まず空のコンストラクタを使ってクラス名を設定してから、すべての属性と方法が直接プロトタイプ属性に与えられます.以下のコードを参照してください.

  function Person(){
  }
  Person.prototype.name = "yzl";
  Person.prototype.sex = "male";
  Person.prototype.sayInfo = function(){
    alert("name : " + this.name + " ,sex :" + this.sex);
  };
  var p1 = new Person();
  p1.sayInfo();
  p1.name = "gcm";
  p1.sex = "female";
  p1.sayInfo(); 
   プロトタイプでインスタンスを作成すると、作成するオブジェクトにプロトタイプのすべての属性が付与されます.すべての属性は同じオブジェクトに見えますが、sayInfoメソッドは同じ参照を指します.この方法を使用してクラスを定義することは、インスタンス指向のタイプを検査するために、instrancof演算子を使用することができる.

  alert(p1 instanceof Person); //true
プロトタイプ方式を採用することによって、前に述べた劣勢があります.ある実例の属性は、オブジェクトが作成された後に、具体的な状況によって修正されることができます.これは全部受け入れられます.しかし、すべての属性が同時に同じ参照を指すため、深刻な問題があります.コードを参照してください.

  function Person(){
  }
  Person.prototype.name = "yzl";
  Person.prototype.sex = "male";
  Person.prototype.friends = new Array("ymj","gcm");
  Person.prototype.sayInfo = function(){
    alert("name : " + this.name + " ,sex :" + this.sex);
  };
  var p1 = new Person();
  var p2 = new Person();
  p1.friends.push("hl");
  alert(p2.friends); // ymj gcm hl
   コードの中ではp 1のfriends属性だけを修正しましたが、p 2のfriends属性も変化しました.これは非常に深刻なエラーです.個人的にはこのような方式はスレッドが安全ではないので、複数のスレッドにアクセスするとエラーが発生します.こんなに多くの修正を経て、より合理的な方法を提案しました.
コンストラクタとプロトタイプ方式を共同で使用した.
4、コンストラクタとプロトタイプの共同使用
この方法は実はとても簡単です.基本的な考え方は
構造関数を用いてクラスの属性を定義し、プロトタイプ方式を用いてクラスを宣言する方法.このようにして、すべてのオブジェクトが独自の属性を持つことができます.そして、すべての方法が一回だけ作成されることを保証します.コードは以下の通りです.

  function Person(sName,sSex){
    this.name = sName;
    this.sex = sSex;
    this.friends = new Array();
  }

  Person.prototype.makeFriend = function(newFriend){
    this.friends.push(newFriend);
  }

  Person.prototype.sayInfo = function(){
    alert("name : " + this.name + " ,sex :" + this.sex + ", and has  friends :" + this.friends );
  };
  var p1 = new Person("yzl","male");
  var p2 = new Person("gcm","female");
  p1.makeFriend("zxt");
  p2.makeFriend("gr");
  p1.sayInfo();
  p2.sayInfo();
   上のこのような方式はすでにjavaの中で一つの対象を創建しました.これもECMAScriptが主に採用した方式です.他にもいくつかの種類の作成方法がありますが、一番効果的なものを覚えておけばいいと思います.他の方法はもう紹介しないで、最後にjavascriptの重載を実現する方法を補充します.まず最初にJavascriptの中の重要な属性を理解しなければなりません.
argmentsは、関数を呼び出したときに渡されるパラメータ、すなわち関数の重負荷を記録できます.コードは以下の通りです.

  function Person(sName,sSex){
    switch(arguments.length){
	case 0 :
	  this.name = "unKnown";
	  this.sex = "unKnown";
	  break;
	case 1 :
	  this.name = sName;
	  this.sex = "unKnown";
	  break;
	case 2 :
	  this.name = sName;
	  this.sex = sSex;
	  break;			
	};
  }

  Person.prototype.sayInfo = function(){
    alert("name : " + this.name + " ,sex :" + this.sex);
  };

  var p1 = new Person("yzl","male");
  var p2 = new Person("gcm");
  var p3 = new Person();
  p1.sayInfo();
  p2.sayInfo();
  p3.sayInfo();