要弄懂原型鏈,首先應先明白prototype原型物件、__proto__、物件三者之間的關系,
引入建構式的相關定義:
建構式是一種比較特殊的函式,用于批量實體化物件,通俗一點說,建構式是用于生成物件的模板,
由于工廠模式在實體化物件時會存在同一功能代碼在記憶體中開辟不同記憶體空間從而造成記憶體空間浪費的問題,更多的人選擇使用建構式來實體化物件,es6中引進的class關鍵字正是基于建構式的思想
建構式的本質上是將物件中一些公共的方法和屬性 抽取出來,然后將這個函式封裝成可復用的建構式.
建構式的特點(與工廠函式相比較):
a. 函式名首字母大寫;
b. 函式體內沒有關鍵字new,在實體化一個物件時會使用關鍵字new;
c. 建構式體內的this指代當前實體化物件;
d. 函式體內沒有關鍵字return,
function Fn() {
this.n = 20
}
Fn.prototype.say= function() {
console.log(this.n)
}
var deb = new Fn()
建構式的new關鍵字在實體化物件時會做以下四件事:
a.現在記憶體中開辟一塊記憶體空間(new obj);
b.讓建構式體內的this指向這個物件 (因而,this指代當前物件);
c.將建構式體內的屬性和方法賦值給這個這個物件;
d.回傳這個物件 (因而,建構式體內沒有return關鍵字)
為了區別對待,以下將建構式稱為父類,將實體化物件稱為子類,
一:原型
1.定義
每一個函式身上都有一個prototype(原型),由于這個prototype的值是一個物件型別,因而又叫做原型物件,ptototype屬性是函式獨有的屬性!
2.原型的作用
原型物件的作用通常用來共享父類的方法,由于方法是函式,本質上也是一個物件,而物件的記憶體地址保存在堆空間里,如同工廠模式一般,多個記憶體空間存放相同的代碼,會造成大量空間被占用,因而將公有的方法添加在父類的prototype上,也就是寫入了同一物件上,呼叫的時候也就避免了多個空間存放同一代碼的錯誤示范,而由于父類的屬性的值是基本型別,所占記憶體較少,所以我們往往將其添加到父類函式體的內部,
function Fn() {
this.n = 20
}
Fn.prototype.sing = function() {
console.log(this.n)
}
var deb = new Fn()
var deb2 = new Fn()
console.log(deb.sing === deb2.sing) //true
二:__proto__
與函式的prototype屬性不同,每一個obj的物件都有一個__ptoto__屬性,這個__proto__屬性隱式的指向了這個子類的的建構式的prototype屬性!但是這個__proto__屬性是不可見的,這也就是為什么將其稱作是隱式的,不過好在瀏覽器的支持下,它被定義為__proto__
如果看到這里,希望你再好好思考一下 ”萬物皆物件“這句話的含義
從父類的角度看,子類的_proto_屬性隱式指向了它的父類的prototype物件;從子類的角度看,子類自身的__proto__屬性指向了它的父類的prototype屬性
假如我們對比父類的prototype與子類的__proto__屬性:
console.log(Fn.prototype === deb.__proto__)//true
理解了這一點,就可以明白為什么建構式添加在其原型物件上的方法,實體化物件可以共享使用了:因為建構式的prototype屬性指向的 與 實體化物件的__proto__屬性指向的 是同一個物件,也就是父類的prototype物件!
這樣,就具備了深入理解原型鏈的條件,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/176996.html
標籤:JavaScript
上一篇:裝飾你的敲門磚,離大廠更進一步
下一篇:使用webpack命令打包時,報錯TypeError: Cannot read property 'presetToOptions' of undefined的解決辦法
