摘要:可以看出這個構(gòu)造函數(shù)是由創(chuàng)建出來的,而我們看下的隱式原型,竟然是指向了的原型,也就是也是由創(chuàng)建出來的。例如,其他構(gòu)造函數(shù)的原型將覆蓋屬性并提供自己的方法。將構(gòu)造函數(shù)的執(zhí)行對象賦給這個空對象并且執(zhí)行。把對象的隱式原型指向構(gòu)造函數(shù)的原型。
構(gòu)造函數(shù)與實(shí)例對象
又是這個經(jīng)典的問題,嗯,我先來寫個構(gòu)造函數(shù),然后實(shí)例化一個對象看看。
function Person(name) { this.name = name } Person.prototype.eat = () => {console.log("eat")} Person.prototype.play = () => {console.log("play")} let Han = new Person("Han")
通過一系列打印發(fā)現(xiàn)了這樣的關(guān)系:
可以看出實(shí)例對象沒有prototype(也就是原型),只有構(gòu)造器才擁有原型。而所有的js對象都擁有__proto__(也就是隱式原型),這個隱式原型所指向的就是創(chuàng)造這個對象的構(gòu)造器的原型。如實(shí)例Han的隱式原型指向了其構(gòu)造函數(shù)(Person)的原型;Person的隱式原型指向了Function的原型;而原型自身也有隱式原型,指向了Object的原型。
有點(diǎn)繞口,其實(shí)就是通過隱式原型可以向上找到是誰構(gòu)造了自己,并且如果自己沒有相應(yīng)的屬性或者方法,可以沿著這條原型鏈向上找到最近的一個屬性或方法來調(diào)用。如Han.eat(),實(shí)際上是調(diào)用了Han.__proto__.eat(),把構(gòu)造器Person的原型的eat方法給拿來用了;再如Han.hasOwnProperty("name"),實(shí)際上是調(diào)用了Han.__proto__.__proto__.hasOwnProperty("name"),因?yàn)镠an自己沒hasOwnProperty這方法,就通過隱式原型向上找到了Person的原型,發(fā)現(xiàn)也沒這方法,就只能再沿著Person的原型的隱式原型向上找到了Object的原型,嗯然后發(fā)現(xiàn)有這方法就拿來調(diào)用了。
構(gòu)造器constructor所有構(gòu)造函數(shù)都有自己的原型(prototype),而原型一定有constructor這么個屬性,指向構(gòu)造函數(shù)本身。也就是告訴大家這個原型是屬于本構(gòu)造函數(shù)的。
Function & Object可以看出Person這個構(gòu)造函數(shù)是由Function創(chuàng)建出來的,而我們看下Function的隱式原型,竟然是指向了Function的原型,也就是Function也是由Function創(chuàng)建出來的。很繞是不是,我們先不管,繼續(xù)溯源下去,再看下Function的原型的隱式原型,指向的是Object的原型,繼續(xù)往上找Object的原型的隱式原型,嗯終于結(jié)束了找到的是null,也就是Object的原型是原型鏈上的最后一個元素了。
接下來看下Object,Object是由Function創(chuàng)建出來的,而Function的隱式原型的隱式原型是Object的原型也就是Function通過原型鏈可以向上找到Object的原型,兩者看起來是你生我我生你的關(guān)系,這里也就引用比較好懂的文章來解釋下: 從Object和Function說說JS的原型鏈
Object
JavaScript中的所有對象都來自O(shè)bject;所有對象從Object.prototype繼承方法和屬性,盡管它們可能被覆蓋。例如,其他構(gòu)造函數(shù)的原型將覆蓋constructor屬性并提供自己的toString()方法。Object原型對象的更改將傳播到所有對象,除非受到這些更改的屬性和方法將沿原型鏈進(jìn)一步覆蓋。Function
Function 構(gòu)造函數(shù) 創(chuàng)建一個新的Function對象。 在 JavaScript 中, 每個函數(shù)實(shí)際上都是一個Function對象。---- 來自mozilla
接下來說下構(gòu)造函數(shù)實(shí)例化對象到底做了些啥,其實(shí)看也能看出來了。
let Jan = {} Person.call(Jan, "Jan") Jan.__proto__ = Person.prototype
1、創(chuàng)建一個空對象。
2、將構(gòu)造函數(shù)的執(zhí)行對象this賦給這個空對象并且執(zhí)行。
3、把對象的隱式原型指向構(gòu)造函數(shù)的原型。
4、返回這個對象
是的就是這樣,next page!
繼承 原型鏈繼承function Person(name) { this.name = name this.skills = ["eat", "sleep"] } Person.prototype.say = ()=> {console.log("hi")} function Boss() {} Boss.prototype = new Person() let Han = new Boss()
原理就是這樣
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/102575.html
摘要:組合繼承實(shí)現(xiàn)了屬性分離,方法共享下的完美繼承方案繼承我們的主角,,就是對組合繼承的改進(jìn)。這也是為什么在子類構(gòu)造函數(shù)中一定要顯示調(diào)用的原因。 談到繼承,或者更廣義上的:一個對象可以使用另外一個對象的屬性或方法。實(shí)現(xiàn)起來無外乎有兩種方式:apply or call 改變this的作用域原型繼承 改變__proto__指向,添加作用域鏈 而JavaScript所有的繼承實(shí)現(xiàn),都是圍繞以上兩點(diǎn)...
摘要:這個構(gòu)造函數(shù)的不管從調(diào)用方式還是內(nèi)部寫法就都很有的感覺,但是從用途上來說,它其實(shí)更靠近的概念是中的工廠方法。到這里,所有關(guān)于繼承的東西講完了,接下來準(zhǔn)備準(zhǔn)備說說當(dāng)中的封裝 所謂的對象,就是抽象化的數(shù)據(jù)本身 一個面向?qū)ο筠D(zhuǎn)向面向原型的困惑 我發(fā)現(xiàn)Javascript這門語言每次翻開都會帶給人新感受,尤其是看完其他語言的面向?qū)ο笤賮砜此侨绻阋彩沁^來人就一定記得教科書里面冗長乏味的...
摘要:深入系列第十五篇,講解各種繼承方式和優(yōu)缺點(diǎn)。優(yōu)點(diǎn)融合原型鏈繼承和構(gòu)造函數(shù)的優(yōu)點(diǎn),是中最常用的繼承模式。寄生組合式繼承為了方便大家閱讀,在這里重復(fù)一下組合繼承的代碼組合繼承最大的缺點(diǎn)是會調(diào)用兩次父構(gòu)造函數(shù)。 JavaScript深入系列第十五篇,講解JavaScript各種繼承方式和優(yōu)缺點(diǎn)。 寫在前面 本文講解JavaScript各種繼承方式和優(yōu)缺點(diǎn)。 但是注意: 這篇文章更像是筆記,哎...
摘要:此時的原型對象包括一個指向另一個原型的指針,相應(yīng)的,另一個原型中的指向另一個構(gòu)造函數(shù)。這種關(guān)系層層遞進(jìn),就通過一個原型對象鏈接另一個構(gòu)造函數(shù)的原型對象的方式實(shí)現(xiàn)了繼承。 讀這篇之前,最好是已讀過我前面的關(guān)于對象的理解和封裝類的筆記。第6章我一共寫了3篇總結(jié),下面是相關(guān)鏈接:讀《javaScript高級程序設(shè)計(jì)-第6章》之理解對象讀《javaScript高級程序設(shè)計(jì)-第6章》之封裝類 一...
摘要:繼承前言作為一門輕量級的腳本語言在和的橫空出世之后將其推向的新的高度雖然中出現(xiàn)的新的生成對象的類語法格式但依然為的語法糖而我們依然有必要從的原生實(shí)現(xiàn)入手來了解它的繼承實(shí)現(xiàn)方式給出了更加簡潔的固定的類聲明方式有興趣的可以查看阮一峰的入門下面給 javascript繼承 前言 javascript作為一門輕量級的腳本語言在ES6和node.js的橫空出世之后將其推向的新的高度,雖然 ES6...
閱讀 2919·2021-10-19 10:09
閱讀 3140·2021-10-09 09:41
閱讀 3391·2021-09-26 09:47
閱讀 2702·2019-08-30 15:56
閱讀 604·2019-08-29 17:04
閱讀 993·2019-08-26 11:58
閱讀 2515·2019-08-26 11:51
閱讀 3369·2019-08-26 11:29