【JavaScript】JS 的原型鏈
本篇大綱:
- 原型是什麼
- 原型鏈是什麼
- 檢查屬性以及實例的方法
JavaScript 的物件通過原型 (Prototype) 機制來達到相互繼承功能。當使用 Constructor Function 創造 object 時,所創造出來的物件不共享 constructor 的屬性和方法。說創造出來的物件稱為實例 ( instance ).
1 | // prototype 例子 |
person_one 和 person_two 的 gender 屬性是獨立的,因此在修改 person_two 的 gender 時,不會影響到 person_one,兩個函式之間不共享屬性。
原型 Prototype
如果要讓所有實例都共享同一個屬性,可以運用實例的特性:當函式以構建函式的形式創建的時候,所創建的物件都有一個隱含的屬性( __ proto __ ),指向該構建函式的原型物件。
因此如果將屬性設置到 prototype,所有函式都能夠存取到該屬性。設置的方式為:FunctionName.prototype.variable
.
Person 這個函式物件以及他的實例的 __ proto __ 指向的是同一個 prototype。這裡將 gender 這個屬性設置到 prototype,因此所有實例都可以取得這個屬性。
person_one 這個實例另外設置了 gender 屬性。當呼叫物件的屬性時,首先會查找自身物件是否有該屬性,有的話就會回傳本身的,沒有的話則會往上一層 prototype 找,直到找到該屬性為止,如果到頂層都沒有找到就會回傳 undefined。因此,person_one.gender
會回傳 female
, 而 person_two.gender
回傳 male
.
1 | // prototype 例子 |
小結:
- 原型物件就像是一個公共區域,同一個構造函式的實例都可以取得這個原型物件。
- 當呼叫物件的屬性時,如果物件有該屬性,就會使用自身的;沒有的話就會往 prototype 找。
- prototype 裡也可以設置 function
- 如果普通函式呼叫 prototype method,並不會起任何作用。
關於原型鏈
實例的 __ proto __ 會指向 constructor 的 prototype。 如果呼叫某個物件的屬性,如 person_two.gender
, 如果在自身 object 裡找不到,就會往上一層 Person.prototype
找,如果還是沒有,就找 Person.prototype.__ proto __
,直到找到某個東西的 __ proto __ 是 null 為止。
眾多 __ ptoto __ 串起來的鏈就稱為原型鏈。通過原型鏈,可以達成類似繼承的功能,得以呼叫自己 parent 的 method.
PS: Person.__ proto __
是 Function.prototype
, Person 是 Function 的 instance.
1 | function Person(first,last) { |
其他
檢查屬性
in
: 使用in
檢查物件中是否含有某個屬性,如果物件中沒有,但 prototype 有會返回true
object.hasOwnProperty()
: 檢查物件自身有沒有這個屬性
1 | //檢查屬性 |
檢查實例
instanceOf
: 檢查函式是不是某個 constructor 的 instance , 會往上搜查原型鏈。
1 | //檢查實例 |