JavaScript對象的深刻理解(二)

以前提到,構造函數方法建立對象存在着方法不共享的問題,所以引伸出了原型模式建立對象javascript

原型模式

原型模式旨在建立一個模版對象,該對象的全部屬性和方法被其實例所共享。java

原型的概念

不一樣於構造函數模式建立對象只能單級即成,得益於原型鏈的概念,原型模式可實現相似其餘OOP語言的多級繼承。函數

原型鏈:一系列有繼承關係的函數(對象)中[[prototype]]屬性自底向上的指向this

先給一個例子:prototype

function Person() {
    
}

Person.prototype = {
      constructor: Person,
    name: "Jonathan",
    age: 23,
      job: developer,
      sayName: function() {
        console.log(this.name);
    }
}

person1 = new Person();
person2 = new Person();

該例子中各對象的關係以下code

//對象

每個函數(對象)均可以視爲一個模版,向上看,該對象的[[prototype]]繼承

建立原型對象

function Person() {
}

Person.prototype = {
      constructor: Person,
    name: "Jonathan",
    age: 23,
      job: developer,
      sayName: function() {
        console.log(this.name);
    }
}

var person1 = new Person();
person1.sayName(); //"Jonathan"

var person2 = new Person();
person2.sayName(); //"Jonathan"

console.log(person1.sayName == person2.sayName); //true

要點ip

  1. 先命名一個空函數
  2. 用對象字面量方式,爲該函數的.prototype屬性添加原型屬性及方法
  3. 爲了constructor屬性的正確指向,應先把constructor指向該對象

原型對象的問題

因爲衆多實例共享原型的屬性,所以改變其中某個實例的屬性會影響到全局,形成屬性污染,例子以下:原型鏈

function Person(){
}

Person.prototype = {
    constructor: Person,
    name : "Nicholas",
    age : 29,
    job : "Software Engineer",
    friends : ["Shelby", "Court"],
    sayName : function () {
        alert(this.name);
    }
};

var person1 = new Person();
var person2 = new Person();

person1.friends.push("Van");

alert(person1.friends);    //"Shelby,Court,Van"
alert(person2.friends);    //"Shelby,Court,Van"
alert(person1.friends === person2.friends);  //true

可見,person1的friends屬性污染了person2的friends屬性。爲避免這種狀況,引入組合構造函數與原型模式。

組合使用構造函數與原型模式

單一使用原型對象的問題在於全部屬性皆共享,若不想共享某屬性,則可放入構造函數中。

function Person(name, age, job){
   this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["Boy next door", "Deep dark fantasy"];
}

Person.prototype = {
    constructor: Person,
    sayName : function () {
        alert(this.name);
    }
};

var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");

person1.friends.push("Van");

alert(person1.friends);    //"Shelby,Court,Van"
alert(person2.friends);    //"Shelby,Court"
alert(person1.friends === person2.friends);  //false
alert(person1.sayName === person2.sayName);  //true
相關文章
相關標籤/搜索