引言
在學習JavaScript
時,不可避免的接觸到了原型和原型鏈的概念,結果被constructor
,prototype
,__proto__
這些屬性搞得一臉懵逼,這些都是什麼鬼!!!通過谷歌瀏覽器除錯時,看物件例項的內部結構,這三個屬性也是你中有我,密不可分,完全理不清頭緒。最後通過理清概念,不斷驗證,最終有了一些思路。
概念
要想真正弄清楚constructor
,prototype
,__proto__
這些屬性的之間的區別和聯絡,首先我們要明確定義:
constructor
屬性始終指向建立當前物件的建構函式。prototype
屬性是每個函式物件都具有的屬性,被稱為原型物件,因為其本身也是個物件。__proto__
屬性是每個物件具有的屬性。一旦原型物件被賦予屬性和方法,那麼由相應的建構函式建立的例項物件會繼承prototype
上的屬性和方法。
事例
下表列出了例項物件和函式物件的區別:
constructor | prototype | __proto__ | |
---|---|---|---|
A | ✔︎ | ✔︎ | ✔︎ |
a | ✔︎ | ✘ | ✔︎ |
由上表可以看出例項物件是沒有prototype
屬性的,只有函式物件才有(這一點很重要!!!),下面用程式碼來具體解釋下以上三個屬性的關係:
<script type="text/javascript">
function A() {};
var a = new A();
</script>
複製程式碼
JavaScript
實際上執行的是:
<script type="text/javascript">
function A() {};
var a = new Object();
a.__proto__ = A.prototype;
A.call(a);
</script>
複製程式碼
其中A.prototype
也是個物件,它由constructor
和__proto__
屬性組成 (這一點很重要!!!),它的構造過程如下:
A.prototype = new Object();
A.prototype.constructor = A;
A.prototype.__proto__ = Object.prototype;
複製程式碼
Object和Function原型物件
-
JavaScript
中的所有物件都來自Object
,所有物件從Object.prototype
繼承方法和屬性,儘管它們可能被覆蓋。例如,其他建構函式的原型將覆蓋constructor
屬性並提供自己的toString()
方法。Object
原型物件的更改將傳播到所有物件,除非受到這些更改的屬性和方法沿原型鏈進一步覆蓋。它的構造過程如下:Object.prototype = new Object(); Object.prototype.constructor = Object; Object.prototype.__proto__ = null; ... Object.__proto__ = Function.prototype; 複製程式碼
-
全域性的
Function
物件沒有自己的屬性和方法, 但是, 因為它本身也是函式,所以它也會通過原型鏈從Function.prototype
上繼承部分屬性和方法。Function
例項從Function.prototype
繼承了一些屬性和方法。 同其他建構函式一樣, 你可以改變建構函式的原型從而使得所有的Function
例項的屬性和方法發生改變。它的構造過程如下:Function.prototype = new Function(); Function.prototype.constructor = Function; Function.prototype.__proto__ = Object.prototype; ... Function.__proto__ = Function.prototype; 複製程式碼
驗證
我們通過谷歌瀏覽器來進行除錯,來驗證我們的結論,先來看下Object
原型物件,如下圖:
再來看下Function
原型物件,如下圖:
最後看下a
和_a
例項物件,如下圖:
紅框框住的部分就是所謂的原型鏈,原型鏈中的方法,例項物件a
和_a
都可以訪問,JavaScript
也是用原型鏈來實現繼承的。
另外,還有一件有趣的事情,如下圖:
可以無限延展下去,是不是很有趣,有興趣的同學可以試一下,可以加深你對這三個屬性的理解,哈哈?。
結語
關於怎麼用原型和原型鏈來實現繼承,網上有很多好的博文供大家參考,大家也可以參考以下連結,我在這裡就不再廢話了。本文如有錯誤,希望指正,不勝感激!
參考連結
segmentfault.com/a/119000000…
segmentfault.com/a/119000000…
blog.jobbole.com/9648/