JS 原型模式

SHERlocked93發表於2017-12-14

1. 簡介

原型模式(Prototype pattern),用原型例項指向建立物件的類,使用於建立新的物件的類的共享原型的屬性與方法。

2. 實現

對於原型模式,我們可以利用JavaScript特有的原型繼承特性去建立物件的方式,也就是建立的一個物件作為另外一個物件的prototype屬性值。原型物件本身就是有效地利用了每個構造器建立的物件,例如,如果一個建構函式的原型包含了一個name屬性(見後面的例子),那通過這個建構函式建立的物件都會有這個屬性。

在現有的文獻裡檢視原型模式的定義,沒有針對JavaScript的,你可能發現很多講解的都是關於類的,但是現實情況是基於原型繼承的JavaScript完全避免了類(class)的概念。我們只是簡單從現有的物件進行拷貝來建立物件。

真正的原型繼承是作為最新版的ECMAScript5標準提出的,使用Object.create方法來建立這樣的物件,該方法建立指定的物件,其物件的prototype有指定的物件(也就是該方法傳進的第一個引數物件),也可以包含其他可選的指定屬性。例如Object.create(prototype, optionalDescriptorObjects),下面的例子裡也可以看到這個用法:

// 因為不是建構函式,所以不用大寫
var someCar = {
    drive: function () { },
    name: '馬自達 3'
};

// 使用Object.create建立一個新車x
var anotherCar = Object.create(someCar);
anotherCar.name = '豐田佳美';

Object.create執行你直接從其它物件繼承過來,使用該方法的第二個引數,你可以初始化額外的其它屬性。例如:

var vehicle = {
    getModel: function () {
        console.log('車輛的模具是:' + this.model);
    }
};

var car = Object.create(vehicle, {
    'id': {
        value: MY_GLOBAL.nextId(),
        enumerable: true // 預設writable:false, configurable:false
},
    'model': {
        value: '福特',
        enumerable: true
    }
});

這裡,可以在Object.create的第二個引數裡使用物件字面量傳入要初始化的額外屬性,其語法與Object.definePropertiesObject.defineProperty方法類似。它允許您設定屬性的特性,例如enumerable, writableconfigurable

如果你希望自己去實現原型模式,而不直接使用Object.create 。你可以使用像下面這樣的程式碼為上面的例子來實現:

var vehiclePrototype = {
    init: function (carModel) {
        this.model = carModel;
    },
    getModel: function () {
        console.log('車輛模具是:' + this.model);
    }
};

function vehicle(model) {
    function F() { };
    F.prototype = vehiclePrototype;

    var f = new F();

    f.init(model);
    return f;
}

var car = vehicle('福特Escort');
car.getModel();

3. 總結

原型模式在JavaScript裡的使用簡直是無處不在,其它很多模式有很多也是基於prototype的,這裡大家要注意的依然是淺拷貝和深拷貝的問題,免得出現引用問題。

原型模式適合在建立複雜物件時,對於那些需求一直在變化而導致物件結構不停地改變時,將那些比較穩定的屬性與方法共用而提取的繼承的實現。


本文是系列文章,可以相互參考印證,共同進步~

  1. JS 抽象工廠模式
  2. JS 工廠模式
  3. JS 建造者模式
  4. JS 原型模式
  5. JS 單例模式
  6. JS 回撥模式
  7. JS 外觀模式
  8. JS 介面卡模式
  9. JS 利用高階函式實現函式快取(備忘模式)
  10. JS 狀態模式
  11. JS 橋接模式
  12. JS 觀察者模式

網上的帖子大多深淺不一,甚至有些前後矛盾,在下的文章都是學習過程中的總結,如果發現錯誤,歡迎留言指出~

參考:
設計模式之原型模式
《Javascript 設計模式》 - 張榮銘

相關文章