對於不少前端開發者而言,JavaScript的原型實在是很讓人頭疼,因此我這邊就整理了一下本身對應原型的一點理解,分享給你們,供交流使用前端
提及原型,那就不得不說prototype、__proto__、constructor三者的關係,其中比較麻煩的就是容易將prototype和__proto__混淆,這也是由於它們之間的指向確實有些複雜函數
function Heternally(){}; var f1 = new Heternally;
經過上述兩行代碼先建立一個函數對象,而後使用new實例化對象。學習
在講原型以前,先簡單介紹一下幾個概念:spa
構造函數.net
例如上述代碼建立的Heternally()函數就被稱爲構造函數。是用來初始化新建立的對象的函數。prototype
構造函數有一個prototype屬性,它指向實例對象的原型對象。同一個構造函數實例化獲得的多個對象具備相同的原型對象,因此常常使用原型對象來實現繼承。調試
實例對象code
經過new操做構造函數所建立的對象是實例對象。一個構造函數能夠實例化多個實例對象,可是獲得的各個實例對象並不相等。對象
實例對象有個proto屬性,指向該實例對象對應的原型對象。blog
又由於實例對象能夠繼承原型對象的屬性,因此實例對象也擁有constructor屬性,指向原型對象對應的構造函數
原型對象
原型對象有一個constructor屬性,指向該原型對象對應的構造函數
w3c上對於 prototype 屬性的定義是它使您有能力向對象添加屬性和方法
1. prototype是函數纔有的屬性
2. __proto__是每一個對象都有的屬性
3. __ptoto__其實是某個實體對象的屬性,而prototype則是屬於構造函數的屬性。__ptoto__只能在學習或調試的環境下使用。
它的指向取決於對象建立時的實現方式,這裏就介紹兩種經常使用方式建立對象後,它指向誰
字面量方式
構造器方式
因爲__proto__是任何對象都有的屬性,而js中萬物皆對象,因此會造成一條__proto__連起來的鏈條,遞歸訪問__proto__必須最終到頭,而且值是null。
當js引擎查找對象的屬性時,先查找對象自己是否存在該屬性,若是不存在,會在原型鏈中查找,但不會查找自身的prototype
圖片取自原型鏈
全部的對象都有__proto__屬性,該屬性對應該對象的原型.
全部的函數對象都有prototype屬性,該屬性的值會被賦值給該函數建立的對象的_proto_屬性.
全部的原型對象都有constructor屬性,該屬性對應建立全部指向該原型的實例的構造函數.
函數對象和原型對象經過prototype和constructor屬性進行相互關聯.