Jeff的隨手筆記

學習當一個前端工程師

0%

『JavaScript 基礎』 JavaScript繼承和原型鍊

Imgur

這是一門在Udemy 課程,是同學介紹的。主要是因為想要運用到過年前這段時間好好的增進自己的JavaScript的基礎能力,讓自己能往前端工程師更近一步。主要還是會以筆記的形式做呈現!


這個篇我們來看一下什麼是繼承和原型鍊

Inheritance(繼承)

繼承可以分成兩種,一種是 classical inheritance,這種方式用在 C# 或 JAVA 當中;另一種則是 JavaScript 所使用的,是屬於 prototypal inheritance。

prototype chain(原型鍊)

Imgur

假設我們現在有一個物件,就稱作 obj ,而這個物件包含一個屬性(property),我們稱作 prop1。

如果現在我們想要prop1的屬性值,我只要使用 obj.prop1 的方式就可以直接讀取到 prop1的屬性值。

在之前的課程我們有學到,JavaScript 裡會有一些預設的屬性和方法,因此所有的物件和函式都有包含 prototype 這個屬性,現在假設我們把 prototype 叫做 proto。

這時候如果我們打上 obj.prop2 時,JavaScript 引擎會先在 obj 這個物件的屬性裡去尋找有沒有叫作 prop2 的屬性,如果它找不到,這時候它就會再進一步往該物件的 proto 裡面去尋找。

如果打成obj.proto.prop2相信大家會比較了解,但因為prototype chain的特性我們不需要這樣打。

每一個物件裡面都包含一個 prototype,包括物件 proto 本身也不例外,因此如果我要找prop3的話也是只要打上obj.prop3就可以了,JavaScript一樣會照上面的步驟執行。因此,從物件本身往 proto 尋找下去的鍊我們就稱作「原型鍊(prototype chain)」。

P.S.它會一直找下去直到某個對象的原型為 null 為止(也就是不再有原型指向)。

範例

我們用實際例子來加強印象:
(這個例子只是為了用來說明 prototype chain 的概念,講師有特別強調寫code時千萬不要使用這樣的方式!)

1
2
3
4
5
6
7
8
9
10
11
12
var person = {
firstname: 'Default',
lastname: 'Default',
getFullName: function() {
return this.firstname + ' ' + this.lastname;
}
}

var john = {
firstname: 'John',
lastname: 'Doe'
}

記住!!!這只是為了說明才這樣打的,實際寫code千步不要這樣寫,因為會有效能上的問題!!!

剛剛的講解讓我們知道所有的物件裡面都會包含原型(prototype)這個物件,在 JavaScript 中這個物件的名稱為 __proto__

因此,我們做以下的步驟:

1
2
3
john.__proto__ = person;
console.log(john.getFullName());
console.log(john.firstname);

首先,我們讓john 這個物件就繼承了 person 物件。

根據剛剛所學的,如果原本 john 這個物件中找不到這個屬性名稱或方法時,JavaScript 引擎就會到 __proto__ 裡面去找,因此第二行的code就會輸出:John Doe

那如果他直接在john 這個物件中找到這個屬性名稱或方法時,JavaScript 引擎就不會到 __proto__ 裡面去找,因此第三行的code就會輸出:John

再往下走,如果這時候我在加一個新的物件:

1
2
3
4
5
6
var jane = {
firstname: 'Jane'
}

jane.__proto__ = person;
console.log(jane.getFullName());

輸出會是:

1
Jane Default

和你想的一樣吧,因為在 Jane 這個物件裡只有 firstName 這個屬性,所以當 JavaScript 引擎要尋找 getFullName() 這個方法時就會去 __proto__ 去找,而這時候的this是指向Jane(因為是Jane這個object發起調用的),因此他找到了Jane,但Jane這個object沒有lastname,因此他去看了prototype並在那裡找到了lastname,所以我們得到了這個答案!

因此,在 JavaScript 當中,所有的東西(字串、數值、布林值、函式、陣列、物件…)的 prototype 最後都是物件!
詳情可以到:https://pjchender.blogspot.com/2016/06/javascriptprototypeobject.html 來了解!