JavaScript作成対象の5パターン

4395 ワード

原文のリンク
オブジェクトに向けた言語には、クラスの概念、抽象的なインスタンスオブジェクトの共通属性と方法があり、クラスに基づいて、任意の複数のインスタンスオブジェクトを作成することができます.
しかし、JSでは、オブジェクトと純粋なオブジェクトとは異なり、ECMA標準では、JSのオブジェクトを定義します.無秩序属性のセットは、基本値、オブジェクトまたは関数を含むことができます.
JSのオブジェクトは無秩序なセットの値であり、属性または方法には名前があり、この名前に基づいてマッピングの値にアクセスできます.
一、工場モデル
作成対象は工場法に任せて実現され、パラメータを伝達できるが、主な欠点はオブジェクトタイプを識別できないことである.
function createPerson(name, age, job) {
  var o = new Object();
  o.name = name;
  o.age = age;
  o.job = job;
  o.getName = function () {
    return this.name;
  }
  return o; //   return         
}
var person = createPerson('Jack', 19, 'SoftWare Engineer');
二、コンストラクタモード
function Person(name,age,job){
  this.name = name;
  this.age = age;
  this.job = job;
  this.getName = function () {
    return this.name;
  }
}
var person1 = new Person('Jack', 19, 'SoftWare Engineer');
var person2 = new Person('Liye', 23, 'Mechanical Engineer');
コンストラクターモードと工場方法の違いは、
  • は、オブジェクトを明示的に作成しない
  • .
  • 直接に属性と方法をthisオブジェクト
  • に値付けする.
  • リセット文がありません.
  • 上記のPersonコンストラクタによって生成された2つのオブジェクトのperson 1とperson 2はいずれもPersonの例であるので、instance ofを用いて判断することができ、すべてのオブジェクトがObjectを継承するので、person 1 instance of Objectも真に戻る.
    console.log(person1 instanceof Person); // true;
    console.log(person2 instanceof Person); // true;
    console.log(person1 instanceof Object); // true;
    console.log(person2 instanceof Object); // true;
    console.log(person1.constructor === person2.constructor); // ture;
    コンストラクタ方式がいいですが、欠点もあります.オブジェクトを作成する時、特にオブジェクトの属性指向関数に対して、関数の作成例が繰り返されます.上記のコードをもとに、次のように書き換えられます.
    function Person(name,age,job){
      this.name = name;
      this.age = age;
      this.job = job;
      this.getName = getName;
    }
    function getName() {
      return this.name;
    }
    三、原型モード
    JSには各関数にプロトタイプの属性があります.この属性は一つのポインタで、一つのオブジェクトを指します.これはnewオペレータ使用関数によって作成されたすべてのインスタンスのプロトタイプです.
    プロトタイプオブジェクトの最大の特徴は、すべてのオブジェクトインスタンスが、その中に含まれる属性および方法を共有することであり、つまり、すべてのプロトタイプオブジェクトにおいて作成された属性または方法は、すべてのオブジェクトインスタンスによって直接共有されることである.
    function Person() {}
    
    Person.prototype.name = "Jack";
    Person.prototype.age = 29;
    Person.prototype.getName = function () {
      return this.name;
    }
    
    var person1 = new Person();
    var person2 = new Person();
    
    console.log(person1.getName === person2.getName); // ture;
    四、コンストラクタと原型モデルを組み合わせる
    現在最も一般的に使われている定義型の方式は,合成構造関数モードとプロトタイプモードである.
    コンストラクターモードはインスタンスの属性を定義するために使用され、プロトタイプパターンは方法と共有の属性を定義するために使用される.
    このように、各インスタンスには、自分のインスタンス属性のコピーがありますが、相手方の方法の参照を共有し、メモリを最大限に節約します.また、組み合わせモードは、構造関数へのパラメータ伝達をサポートしており、2つの長所を集めることができます.
    function Person(name, age, job) {
      this.name = name;
      this.age = age;
      this.job = job;
      this.lessons = ['Math', 'Physics'];
    }
    Person.prototype = {
      constructor: Person, //             constructor  Object,      Person
      getName: function () {
        return this.name;
      }
    }
    
    var person1 = new Person('Jack', 19, 'SoftWare Engneer');
    person1.lessons.push('Biology');
    
    var person2 = new Person('Lily', 39, 'Mechanical Engneer');
    
    console.log(person1.lessons); // ["Math", "Physics", "Biology"]
    console.log(person2.lessons); // ["Math", "Physics"]
    console.log(person1.getName === person2.getName); // true
    五、ダイナミックモデル
    結合モードにおける例示的な属性は、共有方法(プロトタイプによって定義される)とは分離されており、これは純粋な対象言語とはあまり一致しない.
    動的プロトタイプモードは,構造情報をすべて構造関数にカプセル化し,結合の利点を維持した.
    その原理は、コンストラクタのプロトタイプに共有の方法や属性が定義されているかどうかを判断することによって、定義がなければ、定義プロセスを実行しないということです.
    この方法は一回のプロトタイプ上の方法または属性のみを定義し、構造過程をすべて構造関数にパッケージ化し、プロトタイプに対する修正は直ちにすべての例に反映される.
    function Person(name, age, job) {
      this.name = name;
      this.age = age;
      this.job = job;
      this.lessons = ['Math', 'Physics'];
    }
    if (typeof this.getName) {
      Person.prototype = {
        constructor: Person, //             constructor  Object,      Person
        getName: function () {
          return this.name;
        }
      }
    }
    var person1 = new Person('Jack', 19, 'SoftWare Engneer');
    person1.lessons.push('Biology');
    
    var person2 = new Person('Lily', 39, 'Mechanical Engneer');
    
    console.log(person1.lessons); // ["Math", "Physics", "Biology"]
    console.log(person2.lessons); // ["Math", "Physics"]
    console.log(person1.getName === person2.getName); // true