JavaScript建構式製作手機物件規格的樣板

小明到手機行決定挑選一支手機,手機款式很多但基本上都有相同的功能,僅有少部分的規格上有差異,過去那種資料連連看的方式一定會把資料搞得一團亂 (參考先前的 Javascript 物件 "傳參考" 特性),於是他想到一個新方法,先寫好一個樣板,有需要的格式直接從該樣板取用即可。

手機的規格樣板:
品牌
型號
是否能照相
照相

一般物件寫法的問題

如果使用一般的物件製作手機規格的樣板,就會出現以下的問題,當物件賦予到另一個物件上時,兩者其實是使用相同的資料,當修改後者時前者也會跟著修改 (JavaScript 傳參考的特性)。

var phoneTemplate = {
  brand: 'xxx',
  model: 'z1',
  withCamera: false,
  takePhoto: function () {
    if (this.withCamera) {
      console.log('照相');
    } else {
      console.log('這台沒有照相功能');
    }
  }
}

var sonyPhone = phoneTemplate;
sonyPhone.brand = 'Sony';
console.log(phoneTemplate.brand); // "Sony",原始的 Template 已經被修改到了

雖然先前有介紹到如何將值一一的取出來,但此方法也會完全與樣板斷開關聯性。

建構式

使用 JavaScript 建構式寫法,可以先建立一個範本,接下來新增的物件都會依據此範本作為延伸。

JavaScript 建構式中,我們會使用 function 來建立物件樣板 (只能使用 function,亦不能使用箭頭函式)。

這個結構與前方所使用的結構接近,不同的是:

  • this 則是代表此物件的屬性
  • 可以透過參數來傳入數值
  • 使用 new 來套用此樣板,且最終一樣會產生物件
function PhoneTemplate(brand, modal, withCamera) {
  this.brand = brand;
  this.modal = modal;
  this.withCamera = withCamera || false;
  this.takePhoto = function () {
    if (this.withCamera) {
      console.log(this.modal + ' 照相');
    } else {
      console.log(this.modal + ' 這台沒有照相功能');
    }
  }
}

使用建構式時,盡可能使用大寫開頭,讓合作的朋友也能知道他準備作為建構式之用。

而套用樣板會使用 new 這個方法,並且可以透過傳入參數的方法來改變預設值,接下來會出現兩台手機物件,包含相同的樣板套用上不同的值,但兩者並沒有任何關係。

// 建立兩隻手機,分別傳入 品牌、型號、是否有相機
var sonyPhone = new PhoneTemplate('Sony', 'Z100', true);
var nokiaPhone = new PhoneTemplate('Nokia', '3310', false);

// 直接透過 console.log 來觀看其中的值
console.log(sonyPhone);
{
  brand: 'Sony',
  model: 'Z100',
  withCamera: true,
  takePhoto: function () {
    // ...
  }
}

console.log(sonyPhone == nokiaPhone); // false

兩者也可以獨立運行自己的方法:

sonyPhone.takePhoto(); // Z100 照相
nokiaPhone.takePhoto(); // 3310 這台沒有照相功能

我們這裡可以得知是使用相同樣板,但產生兩者毫無關係的物件,並且可以針對其中一個物件新增修改方法。

sonyPhone.call = function () {
  console.log(this.modal + ' 打電話');
}

sonyPhone.call(); // Z100 打電話
nokiaPhone.call(); // nokiaPhone.call is not a function

到這裡我們可以得知這種建構式可以透過 "同一個物件樣板",不斷地產生 "不同"的物件,每個物件彼此都是獨立的(不會有參考的問題),只不過共用相同的原型。

其中一支手機可以看到 __proto__ 是 PhoneTemplate,這就好像是使用同一個模具產生兩個獨立的物件,我們也可以更新這個模具讓產生的物件有更多的功能。

(此篇文章為網路轉載,如有侵權請告知,會盡速將文章下架!)