3.Contructor(構造器)模式—精讀《JavaScript 設計模式》Addy Osmani著

同系列友情連接:


1.設計模式之初體驗—精讀《JavaScript 設計模式》Addy Osmani著
2.設計模式的分類—精讀《JavaScript 設計模式》Addy Osmani著

Construct(構造器)模式


在經典的面向對象編程語言中,Construtor是一種在內存已分配給該對象的狀況下,用於初始化新建立對象的特殊方法。javascript

在 JavaScript 中,幾乎全部東西都是都是對象,可能你會常常找不到對象,😝,你認可不?😁java

來看一下什麼是 Object構造器 :編程

用於建立特定類型的對象——準備好對象以備使用,同時接受構造器可使用的參數,以在第一次建立對象時,設置成員屬性和方法值。設計模式

下圖爲:Constructor(構造器)模式 編程語言

Object構造器

對象的建立

在 JavaScript 中,建立對象時有發生,常見的建立方式有兩種:模塊化

  1. 直接空對象賦值;
  2. 使用 new關鍵字
// 1. 直接空對象賦值
var newObject = {};

// 2. 使用 new 關鍵字建立,newObject構造器的簡潔記法
var newObject = new Object();
複製代碼

在 Object構造器爲特定的值建立對象封裝,或者沒有傳遞值時,它將建立 一個空對象並返回這個空對象;函數

對象的賦值

四種方法能夠將鍵值賦值給一個對象:post

  1. ECMAScript 3 兼容方式;
    1. 「點」語法;
    2. 中括號語法
  2. 只適用於ECMAScript 5 方式;
    1. Object.defineProperty;
    2. Object.defineProperties
// 1.點語法
// 設置屬性
newObject.someKey = "Hello World!";
// 獲取屬性值
var key = newObject.someKey;


// 2.中括號語法
// 設置屬性
newObject["somekey"] = "Hello world!";
// 獲取屬性值
var key = newObject["somekey"];


// 3.Object.defineProperty
// 設置屬性
Object.defineProperty(newObject,"somekey",{
    value:"Hello World!",// 該屬性對應的值,默認爲undefined
    writable:true,// 可否修改屬性的值,若是直接使用字面量定義對象,默認值爲true
    enumerable:true,// 表示該屬性是否可枚舉,便是否經過for-in循環或Object.keys()返回屬性,若是直接使用字面量定義對象,默認值爲true
    configurable:true// 表示可否經過delete刪除此屬性,可否修改屬性的特性,或可否修改把屬性修改成訪問器屬性,若是直接使用字面量定義對象,默認值爲true
});
// 也能夠簡化一下這種方式
var defineProp = function(obj,key,value){
    config.value=value;
    Object.defineProperty(obj,key,config);
}
// 使用上述方式,先建立一個空的 person對象
var person = Object.create(null);
// 而後設置各個屬性
defineProp(person,"car","Delorean");
defineProp(person,"dateOfBrith","1989");
defineProp(person,"hasBeard",false);
// 獲取屬性值同1,2
var key_car = person["car"];
var key_dateOfBrith = person["dateOfBrith"];
var key_hasBeard = person["hasBeard"];


// 4.Object.defineProperties
// 設置屬性
Object.defineProperties(newObject,{
    "someKey":{
        value:"Hello World!",
        writable:true
    },
    "anotherKey":{
        value:"Foo Bar",
        writable:false
    }
});
// 獲取屬性值同1,2
var key_someKey = person["someKey"];
var key_anotherKey = person["anotherKey"];

複製代碼

上面定義的這些方法甚至能夠用於繼承以下所示:ui

// 用法
// 建立賽車司機 driver 對象,繼承於 person 對象
var driver = Object.create(person);
// 爲 driver 設置一些屬性
defineProp(deriver,"topSpeed","100mph");
// 獲取繼承屬性
console.log(driver.dateOfBrith);
// 獲取咱們設置的100mph屬性
console.log(driver.topSpeed);

複製代碼

基本Constructor(構造器)

你們都知道 JavaScript 不支持類的概念,可是它卻支持與對象一塊兒使用的 特殊的 Constructor 函數。經過在構造器前面加 new關鍵字,告訴 JavaScript 像使用構造器同樣實例化一個新的對象,而且對象成員由該函數定義。this

在構造器內,關鍵字 this引用新建立的對象。回顧對象建立,基本的構造器看起來多是這樣的:

function Car(model,year,miles){
    this.model = model;
    this.year = year;
    this.miles = miles;
    this.toString= function(){
        return this.model+ " has done " + this.miles + " miles";
    }
}
// 用法
var civic = new Car("Honda Civic",2009,20000);
var mondeo= new Car("Ford Mondeo",2010,5000);

console.log(civic.toString());
console.log(mondeo.toString());
複製代碼

上面是一個簡單的構造器模式版本,可是也是存在問題的:由於她很難繼承,另外一個 問題就是 toString()這樣的函數是爲每一個使用 Car 構造器建立的新對象而從新定義的。 這不是最理想的,由於這種函數應該在全部的 Car 實例之間共享。

其實這個問題很好解決,由於有不少ES3和 ES5兼容替代方法可以用於建立對象。

帶原型的Constructor(構造器)

JavaScript中有一個名爲 prototype 的屬性。調用 JavaScript 構造器建立一個對象後,新的對象就具備構造器原型的全部屬性。經過這種方式,能夠建立多個 Car 對象,並訪問相同的原型。因此咱們能夠擴展原始示例,以下所示:

function Car(model,year,miles){
    this.model = model;
    this.year = year;
    this.miles = miles;
}
// 前方警告:小夥伴是否還記得反模式一條:避免從新定義 prototype對象
// 因此下面咱們是使用 Object.prototype.newMethod而不是Object.prototype來定義對象內部的方法
Car.prototype.toString=function(){
    return this.model+ " has done " + this.miles + " miles";
}
// 用法
var civic = new Car("Honda Civic",2009,20000);
var mondeo= new Car("Ford Mondeo",2010,5000);

console.log(civic.toString());
console.log(mondeo.toString());

// 這樣 toString()的單一示實例就能夠在全部的 Car 對象之間共享了
複製代碼

小結

今天的構造器模式,是否是很nice?

可是,你掌握了多少?

你能夠動動小手指示例代碼都敲一遍,相信你能夠更進一步瞭解,掌握 Constructor(構造器)模式。

下一篇將對Module(模塊)模式作詳細的介紹。這一模式更精彩,由於很快你就會知道爲何別人都那麼寫了,以及模塊化的相關概念等等等

( ^_^ )/~~拜拜

相關文章
相關標籤/搜索