前言
如何定義自己的原型
定義自己的原型
在這邊我們定義了兩個物件,等等我們會用建構式的方式產生這兩個物件,並且這兩個物件繼承同一個原型。
情境跟上一篇文章一樣,我們是造物主,我們必須在腦海中先有狗的原型,然後創造出兩隻狗,一隻叫比比,一隻叫噗噗。
var Bibi = {
name: '比比',
color: '棕色',
size: '小',
bark: function () {
console.log(this.name + '吠叫');
}
};
var Pupu = {
name: '噗噗',
color: '白色',
size: '大',
bark: function () {
console.log(this.name + '吠叫');
}
};
這兩隻狗都具有吠叫的方法,也就是說這個方法我們可以定義在這兩隻狗的藍圖上,也就是他們的原型函式。
我們在定義屬性的時候,會利用 this.屬性名稱 = 屬性 的方式定義,這樣在使用 new 的時候就可以客製化的傳入並賦予不同的
屬性內容。
function Dog (name, color, size) {
this.name = name;
this.color = color;
this.size = size;
}
現在 Dog 的函式只是一個藍圖,它並不是一個實體,要讓它變成實體我們就需要使用到 new 的這個運算子。
首先我們先來看一下這個運算子的 相關文件
MDN 文件提到,使用 new 運算子會產生一個 Javascript 的物件,並且會連結回原本的物件(在這邊的例子也就是指說被 new 出來的實體會連結到原本的 Dog 的函式)。另外也會把 this 指向到新產生的實體上。
我們實際做做看 ~
function Dog (name, color, size) {
this.name = name;
this.color = color;
this.size = size;
}
var Bibi = new Dog('比比','棕色', '小');
console.log('Bibi', Bibi);
運行結果:
可以看到印出來之後,展開 Bibi 的 __proto__ 之後,其中的 constructor 屬性指向了 Dog 的函式,代表這個物件是由 Dog 這個函示所創建的。
再來我們一樣創建噗噗這隻狗
var Pupu = new Dog('噗噗','白色', '大');
console.log('Pupu', Pupu);
運行結果:
現在我們兩隻狗都創建出來了,但是你會發現還少了吠叫的方法。
這時候就要用我們上一篇文章提到的 prototype 的方法將共用的函式方法掛載到原型上,也就是 Dog 的原型。
首先我們先 console.dir(Dog); 觀察一下狗這個函式,我們之前也有說過,函示本身就是一個物件。
所以函式裡面有一個通用的屬性叫做 prototype
透過 prototype 所新增的方法,就會作為原型上的屬性,可以被向下的其他原型或是實體給取用到。
所以我們就透過將 bark 這個函式掛載在 Dog 這個原型的 prototype 上:
function Dog (name, color, size) {
this.name = name;
this.color = color;
this.size = size;
}
// 多了這裡喔!!!!!!!
Dog.prototype.bark = function () {
console.log(this.name + '吠叫');
}
// 多了這裡喔!!!!!!!
var Bibi = new Dog('比比','棕色', '小');
console.log('Bibi', Bibi);
var Pupu = new Dog('噗噗','白色', '大');
console.log('Pupu', Pupu);
之後點開來看,這兩隻狗都可以找到 bark 的吼叫功能。
我們就實際呼叫看看!
Bibi.bark(); // 比比吠叫
Pupu.bark(); // 噗噗吠叫
總結
Dog 這個函式又被稱為建構函式,用於建構其他實體所用的。
為什麼我們需要把 bark 的方法掛載在 Dog 的 prototype上呢 ? 主要是因為如果一直撰寫在不同的物件中,會消耗記憶體的容
量,當你需要記載的函式越來越多的時候,記憶體的負擔就會更大。所以透過統一掛載在 Dog 的 prototype 上,可以提高效
率,也方便作修改,一次只要調整一個地方就好,對於程式碼來說也是很好維護的做法。
注意!上一篇文章我們是直接將方法掛載在 __proto__ 的屬性上,但其實這個屬性是用來指向該物件的原型是誰的一個屬性。
如果我們要將共用的函式掛載在原型上的話,最好還是使用 ↓
建構函式名稱.prototype.共用函式名稱 = function (params) {
...
}
雖然
console.log(Dog.prototype === Bibi.__proto__); // true
這樣兩個內容是一樣的,但還是希望大家使用 prototype 去掛載需要用到的共用函式,同時你在除錯的時候,也比較容易找到
問題點在哪裡!