image.png
image.png
- 聲明一個(gè)函數(shù)伦吠,則這個(gè)函數(shù)默認(rèn)會(huì)有一個(gè)屬性叫 prototype 。而且瀏覽器會(huì)自動(dòng)按照一定的規(guī)則創(chuàng)建一個(gè)對(duì)象,這個(gè)對(duì)象就是這個(gè)函數(shù)的原型對(duì)象讨勤,prototype屬性指向這個(gè)原型對(duì)象箭跳。這個(gè)原型對(duì)象有一個(gè)屬性叫constructor 執(zhí)行了這個(gè)函數(shù)晨另,注意:原型對(duì)象默認(rèn)只有屬性:constructor潭千。其他都是從Object繼承而來(lái),暫且不用考慮借尿。
- 通過(guò) new 生成的所有的實(shí)例對(duì)象共享同一個(gè)原型刨晴;
-
原型鏈其實(shí)是一種鏈表的結(jié)構(gòu),將next 換成 __ proto__, 同時(shí)生成一個(gè) contructor 指針指向自己路翻;
image.png
原型鏈就是多個(gè)對(duì)象通過(guò) proto 的方式連接了起來(lái)狈癞。為什么 obj 可以訪問(wèn)到 valueOf 函數(shù),就是因?yàn)?obj 通過(guò)原型鏈找到了 valueOf 函數(shù)茂契。
- Object 是所有對(duì)象的爸爸蝶桶,所有對(duì)象都可以通過(guò) proto 找到它
- Function 是所有函數(shù)的爸爸,所有函數(shù)都可以通過(guò) proto 找到它
函數(shù)的 prototype 是一個(gè)對(duì)象 - 對(duì)象的 proto 屬性指向原型掉冶, proto 將對(duì)象和原型連接起來(lái)組成了原型鏈
image.png
重點(diǎn): 繼承的本質(zhì)其實(shí)是原型鏈的形成真竖;
繼承實(shí)現(xiàn)的效果是:
Child.prototype.__proto__ = Parent.Prototype恢共;(子類原型的 __proto__ 指向父類原型)
// 然后我們知道的是 parent.__proto__ = Parent.Prototype璧亚;
// 所以只要 Child.prototype = parent癣蟋;(子類的原型指向父類的實(shí)例即可,父類的實(shí)例是共享一個(gè)父類的原型對(duì)象的)
應(yīng)用: 原型繼承
- 組合繼承
function Parent() {
this.val = value;
}
Parent.prototype.getValue = function() {
console.log(this.val);
}
function Child(val) {
Parent.call(this, value);
}
Child.prototype = new Parent();
- 核心: 子類的構(gòu)造函數(shù)中通過(guò) Parent.call(this)來(lái)繼承父類的屬性濒生,
然后改變子類的原型為 new Parent() 來(lái)繼承父類的函數(shù)甜攀;
這種繼承的優(yōu)點(diǎn)在于構(gòu)造函數(shù)可以傳參琐馆,不會(huì)和父類應(yīng)用屬性共享瘦麸,可以復(fù)用父類的函數(shù);
缺點(diǎn):繼承父類函數(shù)的時(shí)候調(diào)用了父類的構(gòu)造函數(shù)厉碟,導(dǎo)致子類的原型上多了不需要的父類屬性,存在內(nèi)存上的浪費(fèi)
- 寄生組合繼承 (對(duì)組合繼承優(yōu)化)
function Parent(value) {
this.val = value;
}
Parent.prototype.getValue = function() {
console.log(this.val);
}
function Child() {
Parent.call(this崭参,value)
}
// 創(chuàng)建一個(gè)對(duì)象款咖,以 Parent.protptype 為原型铐殃,而且擁有constructor屬性的;
Child.Prototype = Object.create(Parent.protptype坏逢,{
constructor: {
value: Child,
enumerable: false,
writeable: true,
configurable: true
}
})
核心: 將父類的原型賦值給了子類是整,并且將構(gòu)造函數(shù)設(shè)置為子類
Class 繼承
Class Parent {
constructor(value){
this.val = value;
}
getValue() {
console.log(this.val);
}
}
Class Child extends Parent {
constructor(value) {
super(value)
this.val = value;
}
}
let child = new Child(1)
child.getValue() // 1
child instanceof Parent // true
- class 實(shí)現(xiàn)繼承的核心在于使用 extends 表明繼承哪個(gè)父類贰盗,并且在子類構(gòu)造函數(shù)中必須調(diào)用 super阳欲,因?yàn)檫@段代碼可以看成 Parent.call(this, value).
js 中并不存在類球化,class 語(yǔ)法只是語(yǔ)法糖;
組合繼承圖:
f657770d9caa88ff0f2ddce6adf679f.png
寄生繼承圖:
d7179e0ad06ddce5c4b015297e15f01.png
Class 繼承圖:
0ec8b771ceb3c6eb4ad9f8d126607cd.png