生活随笔
收集整理的這篇文章主要介紹了
JS重点整理之JS原型链彻底搞清楚
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
對象
要清楚原型鏈,首先要弄清楚對象:
?
?
?
-
- 最普通的對象:有__proto__屬性(指向其原型鏈),沒有prototype屬性。
- 原型對象(person.prototype 原型對象還有constructor屬性(指向構造函數對象))
?
- 函數對象:
- 凡是通過new Function()創建的都是函數對象。
? ? ? ? ? ? ? ? ? ? ? ? ? 擁有__proto__、prototype屬性(指向原型對象)。
? ? ? ? ? ? ? ? ? ? ? ? ? Function、Object、Array、Date、String、自定義函數
? ? ? ? ? ? ? ? ? ? ? ? ? 特例: Function.prototype(是原型對象,卻是函數對象,下面會有解釋)
[javascript]?view plaincopy
函數對象??function?f1(){};??var?f2?=?function(){};??var?f3?=?function("n1","n2","return?n1+n2");????console.log(typeof?f1);??console.log(typeof?f2);??console.log(typeof?f3);???console.log(typeof?Object);???console.log(typeof?Array);???console.log(typeof?String);???console.log(typeof?Date);???console.log(typeof?Function);??? Array是函數對象,是Function的實例對象,Array是通過newFunction創建出來的。因為Array是Function的實例,所以Array.__proto__ === ?Function.prototype
[javascript]?view plaincopy
普通對象??var?o1?=?new?f1();???var?o2?=?{};?????????var?o3?=?new?Object();?????console.log(typeof?o1);??console.log(typeof?o2);???console.log(typeof?o3);??? 原型對象
? ? ? ? 每創建一個函數都會有一個prototype屬性,這個屬性是一個指針,指向一個對象(通過該構造函數創建實例對象的原型對象)。原型對象是包含特定類型的所有實例共享的屬性和方法。原型對象的好處是,可以讓所有實例對象共享它所包含的屬性和方法。
第一塊中有提到,原型對象屬于普通對象。Function.prototype是個例外,它是原型對象,卻又是函數對象,作為一個函數對象,它又沒有prototype屬性。
[javascript]?view plaincopy
function?person(){};????console.log(typeof?person.prototype)?console.log(typeof?Object.prototype)?console.log(typeof?Function.prototype)?console.log(typeof?Function.prototype.prototype)? 解釋:
???? functionperson(){};
? ? ? ? 其實原型對象就是構造函數的一個實例對象。person.prototype就是person的一個實例對象。相當于在person創建的時候,自動創建了一個它的實例,并且把這個實例賦值給了prototype。
?
[javascript]?view plaincopy
?function?person(){};??var?temp?=?new?person();??person.prototype?=?temp;????function?Function(){};??var?temp?=?new?Function();??Function.prototype?=?temp;? ?
? ? ? ? 從一張圖看懂原型對象、構造函數、實例對象之間的關系
?
[javascript]?view plaincopy
function?Dog(){};????Dog.prototype.name?=?"小黃";??Dog.prototype.age?=??13;??Dog.prototype.getAge?=?function(){??????return?this.age;??}????var?dog1?=?new?Dog();??var?dog2?=?new?Dog();????dog2.name?=?"小黑";??console.log(dog1.name);?console.log(dog2.name);? ?
?
?
[javascript]?view plaincopy
dog1.__proto__?===?Dog.prototype????Dog.prototype.__proto__?===?Object.prototype???dog1.__proto__.__proto__?===?Object.prototype????Dog.prototype.constructor?===?Dog?????Dog.prototype.isPrototypeOf(dog1)????獲取對象的原型??dog1.__proto__??Object.getPrototypeOf(dog1)?===?Dog.prototype??? ?
原型鏈
原型鏈是實現繼承的主要方法。
?
先說一下繼承,許多OO語言都支持兩張繼承方式:接口繼承、實現繼承。
|- 接口繼承:只繼承方法簽名
|- 實現繼承:繼承實際的方法
由于函數沒有簽名,在ECMAScript中無法實現接口繼承,只支持實現繼承,而實現繼承主要是依靠原型鏈來實現。
?
?
原型鏈基本思路:
?
利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。
?
每個構造函數都有一個原型對象,原型對象都包含一個指向構造函數想指針(constructor),而實例對象都包含一個指向原型對象的內部指針(__proto__)。如果讓原型對象等于另一個類型的實例,此時的原型對象將包含一個指向另一個原型的指針(__proto__),另一個原型也包含著一個指向另一個構造函數的指針(constructor)。假如另一個原型又是另一個類型的實例……這就構成了實例與原型的鏈條。
?
原型鏈基本思路(圖解):
?
?
?
舉例說明:
?
[javascript]?view plaincopy
function?animal(){??????this.type?=?"animal";??}??animal.prototype.getType?=?function(){??????return?this.type;??}????function?dog(){??????this.name?=?"dog";??}??dog.prototype?=?new?animal();????dog.prototype.getName?=?function(){??????return?this.name;??}????var?xiaohuang?=?new?dog();?? ?
[javascript]?view plaincopy
xiaohuang.__proto__?===?dog.prototype??dog.prototype.__proto__?===?animal.prototype??animal.prototype.__proto__?===?Object.prototype??Object.prototype.__proto__?===?null?? 圖解:
?
詳細圖
從xiaohuang這個實例,看出整個鏈條
?
?
總結:
?
Xiaohuang這個Dog的實例對象繼承了Animal,Animal繼承了Object。
轉載于:https://www.cnblogs.com/snowhite/p/9055357.html
總結
以上是生活随笔為你收集整理的JS重点整理之JS原型链彻底搞清楚的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。