JavaScript建立對象(四)——組合使用構造函數和原型模式

JavaScript建立對象(三)——原型模式中,咱們闡述了原型模式存在的兩個問題:一是沒辦法經過構造函數初始化對象屬性,二是共享引用類型的數據致使數據錯亂。因而咱們提出組合使用兩種模式,摒棄它們的缺點,保留它們的優勢。javascript

爲了解決構造函數模式相同功能的函數定義屢次的問題,咱們提出了原型模式。可是不要忘記,構造函數模式也具有原型模式所缺少的優勢,好比能夠經過構造函數初始化對象的屬性,同時也沒有共享引用類型的數據錯亂問題。既然咱們提出原型模式是爲了解決構造函數模式的函數問題,那爲何咱們不僅把函數定義在原型中,屬性依然保留在構造函數中呢?順着這個思路,咱們來看下面的代碼:java

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ['小明', '小剛'];
}

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

var p1 = new Person('張三', 18, 'JavaScript');
var p2 = new Person('李四', 20, 'Java');

p1.friends.push('小紅');
console.log(p1.friends);//["小明", "小剛", "小紅"]
console.log(p2.friends);//["小明", "小剛"]

console.log(p1.friends === p2.friends);//false
console.log(p1.sayName === p2.sayName);//true

仍是原來的例子,只不過把一些不須要共享的屬性保留在構造函數中,須要共享的屬性定義在原型中,這就是組合使用構造函數和原型模式。咱們能夠看到,首先能夠經過構造函數初始化對象屬性了。其次,由於屬性是定義在構造函數中,每次經過new關鍵字建立對象都會執行一次構造函數,因此對於每一個對象來講就都有了屬於本身的屬性了。好比這裏,p1friends新增了一個小紅,p2friends並不會受到影響,由於它們是兩個數組。再者,一些須要共享的屬性依然定義在原型中,避免了重複定義,可謂是集兩種模式之長。數組

這種構造函數與原型集成的模式,是目前在JavaScript中使用最普遍、認同度最高的一種建立自定義類型的方法。能夠說,這是用來定義引用類型的一種默認模式。函數

本文參考《JavaScript高級程序設計(第3版)》this

相關文章
相關標籤/搜索