摘要:譯者注根據(jù)定義,沒有原型,并作為這個原型鏈中的最后一個環(huán)節(jié)。由于這個屬性不標(biāo)準(zhǔn),因此一般不提倡使用。中用函數(shù)獲得一個對象的。
溫馨提示:作者的爬坑記錄,對你等大神完全沒有價值,別在我這浪費(fèi)生命
在上一篇博文javascript對象不完全探索記錄03:小伙子,你對象咋來的?上篇,中大概說了說在js中,比較好理解的對象創(chuàng)建方式,分別是直接定義/字面量,和調(diào)用構(gòu)造函數(shù)
你對象還有原型?在一眾博文及書中,有一個高級/不好看明白的方式,比上面這兩種更收到推崇,那就是大名鼎鼎的原型方式,看到這個詞,我表示不是我謙虛,是真懵逼,啥原型,什么原型,誰的原型?現(xiàn)看看別人給的例子
function Car() { } Car.prototype.color = "blue"; Car.prototype.doors = 4; Car.prototype.mpg = 25; Car.prototype.showColor = function() { alert(this.color); }; var oCar1 = new Car(); var oCar2 = new Car();
源自ECMAScript 定義類或?qū)ο?- W3school
別說,還真有那么點(diǎn)眼熟,這種對象名稱,后面跟一個prototype的寫法,一直以來是我一個重要懵逼來源,話說這詞,不就是原型的意思嗎?
prototype
英 [?pr??t?ta?p] 美 [?pro?t?ta?p]
n.
原型,雛形,藍(lán)本
哈,在這等著我呢,其實(shí)認(rèn)真一看這句Car.prototype.color = "blue";的語法意思是給Car的prototype的color賦值,翻譯一下就是給Car的原型中的color屬性賦值,所以說是不是能理解為原型也就是prototype是對象的一個屬性呢?還是從頭了解吧
所以你原型是啥?提到原型,就不能不提到j(luò)avascript中的一個重要的懵逼概念 - 原型鏈
每個對象都有一個私有屬性(稱之為 [[Prototype]]),它持有一個連接到另一個稱為其 prototype 對象(原型對象)的鏈接。該 prototype 對象又具有一個自己的原型,層層向上直到一個對象的原型為 null。(譯者注:Object.getPrototypeOf(Object.prototype) === null; // true)根據(jù)定義,null 沒有原型,并作為這個原型鏈中的最后一個環(huán)節(jié)。源自MDN Web docs - Web技術(shù)文檔/javascript/繼承與原型鏈
這段話我注意到的有幾個關(guān)鍵詞:每個對象,私有屬性,鏈接,層層向上
用直白的話描述一下,在javascript中任何一個對象都有一個叫做原型對象的對象,這個原型對象就是傳說中的prototype,而指向原型對象的鏈接/指針/箭頭/->/都存在對象內(nèi)部的一個私有屬性中[[Prototype]]中(*見注1)
也就是說對象的[[Prototype]]中并不是直接存了原型對象,而是存著一個指向原型對象的鏈接//這也就使得其是動態(tài)的-待研究
由此可以想到的,既然每個對象都有原型對象,每個對象也都可以作為其他對象的原型對象,那么就會形成一個由[[Prototype]]屬性組成的鏈,這就是傳說中的原型鏈了,而利用原型鏈,對象可以訪問其原型對象的屬性及方法
*注1
[[prototype]]是一個隱藏屬性,但很多瀏覽器都給每一個對象提供.__proto__這一屬性,這個屬性就是上文反復(fù)提到的該對象的[[prototype]]。由于這個屬性不標(biāo)準(zhǔn),因此一般不提倡使用。ES5中用Object.getPrototypeOf函數(shù)獲得一個對象的[[prototype]]。ES6中,使用Object.setPrototypeOf可以直接修改一個對象的[[prototype]]源自知乎問題 - js中__proto__和prototype的區(qū)別和關(guān)系? - 知乎用戶的回答
換句話說,任何一個對象,都是在另一個被叫做原型對象的基礎(chǔ)之上被創(chuàng)建出來的,這也就是所謂的原型了
整這么麻煩干嘛?就像我們知道的,在學(xué)園都市里有好多少女們/對象,她們各自有不同名字,頭發(fā)顏色,以及超能力,她們可以展現(xiàn)自己的超能力,我們建立一個名叫GirlFriend()的構(gòu)造函數(shù),來記錄記錄
function GirlFriend(name,hairColor,power){ this.name = name; this.hairColor = hairColor; this.showPower = function(){ console.log(power) } }
記錄/實(shí)例化炮姐和黑子
var mikoto = new GirlFriend("Mikoto","brown","BiliBili"); var kuroko = new GirlFriend("Kuroko","black","Telesport"); mikoto.showPower();//BiliBili kuroko.showPower();//Telesport
直到這里一切都很正常,但是卻發(fā)現(xiàn)炮姐不是一個人!有人處于某種原因克隆了好多炮姐,如何記錄炮姐的妹妹們呢,我們創(chuàng)建一個構(gòu)造函數(shù)Sister()用于記錄炮姐的妹妹們
function Sister(level,number){ this.level = level; this.number = number; this.showLevel = function(){ console.log(this.level); } }
但是妹妹們也是由炮姐克隆而來的啊,炮姐有的屬性她們也都應(yīng)該有啊,怎么辦,直接在Sister()里新增屬性嗎?太麻煩了而且這就跟炮姐沒關(guān)系了,炮姐哪天要是在GrilFriend()里多錄入一個新的屬性,在Sister()也還得繼續(xù)添加。
就沒有什么更好的方式嗎,答案是肯定的
于是我們就用炮姐這個實(shí)例對象作為原型對象
Sister.prototype = mikoto;
在這里Sister.prototype指的是由構(gòu)造函數(shù)Sister()生成的實(shí)例對象所對應(yīng)的原型對象
說白了,上面這行代碼的的作用就是讓所有由Sister()生成的實(shí)例對象的原型對象都是mikoto,我們來試試結(jié)果
var sister = new Sister(3,"0001"); sister.showPower();//BiliBili sister.showLevel();//3
到此為止一個擁有3級BiliBili能力的妹妹就誕生了
而且其整個的執(zhí)行過程也與我們對鏈的理解一樣,是從內(nèi)到外,從這兒到那兒的
GirlFriend.prototype.age = 14; console.log(sister);//見截圖 console.log(sister.age)//14
從結(jié)果中可以看出,sister對象內(nèi)部并沒有age屬性,在sister對象的原型對象mikoto中也沒有age屬性,但是在mikoto的原型對象中包含age屬性并且有值,所以sister對象就順著原型鏈一路找到了第一個age屬性
但其實(shí)sister的因?yàn)槭潜豢寺〕鰜淼乃灾挥?歲而已
sister.age = 1; console.log(sister);//見截圖 console.log(sister.age)//1
從運(yùn)行結(jié)果可以看出,sister對象內(nèi)部有age屬性,這個是sister原型鏈上第一個age屬性,所以sister.age的值就取1
為由GirlFriend()實(shí)例化對象的原型對象增加屬性age并賦值,看看sister.age
在上文代碼和截圖中出現(xiàn)了兩個和prototype相關(guān)的詞,prototype和_proto_,這倆貨是干啥的?
其實(shí)上文提到了,構(gòu)造函數(shù)Foo()的prototype屬性指的就是這個構(gòu)造函數(shù)所對應(yīng)的原型對象,其實(shí)就是通過Foo()創(chuàng)建的對象的原型對象,所以prototype是構(gòu)造函數(shù)所具有的一個屬性
而_proto_屬性是對應(yīng)對象所說的,見上文注1所說,舉個例子
sister.__proto__.age = 1 console.log(mikoto.age);//1 console.log(kuroko.age);//14 sister.__proto__.__proto__.age = 1 console.log(kuroko.age);//1
正如例子中表現(xiàn)的,對象可以通過_proto_屬性獲得自己的原型對象,以及原型鏈上每一個對象
在截圖中的原型對象中,還存在一個constructor的屬性,這個屬性指向的就是這個原型對象所對應(yīng)的構(gòu)造函數(shù),也就是那個構(gòu)造出原型對象為該對象的函數(shù),一句話概括就是構(gòu)造函數(shù)和其對應(yīng)的對象互相擁有彼此,構(gòu)造函數(shù)將對象放在prototype屬性中,對象將構(gòu)造函數(shù)放在constructor屬性中我想這就是愛情吧
這里再放一張圖,就能更清除解釋他們之間的關(guān)系了
源自知乎問題 - js中__proto__和prototype的區(qū)別和關(guān)系? - doris的回答
話說回來繞了這么大一圈,還沒忘我們?yōu)槭裁匆芯吭桶?,通過原型的方式創(chuàng)建對象的屬性和方法,就可以利用同種對象類型的不同實(shí)例擁有想用的原型對象這一特性,避免重復(fù)創(chuàng)建,并且在修改原型對象的某個屬性后,也可以通過原型鏈影響到其他所有相關(guān)對象上。
舉個例子
GirlFriend.prototype.sayHello = function(){ console.log("Ohayo!") } kuroko.sayHello();//Ohayo! sister.sayHello();//Ohayo!
并且說到底她們執(zhí)行的都是同一個sayHello()
關(guān)于原型這塊概念相對復(fù)雜,還設(shè)計(jì)嵌套,相互引用等等深坑,還是得先捋清楚再自己多做聯(lián)系來理解和熟練運(yùn)用啦
能看到這的估計(jì)都懵逼了
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/92275.html
摘要:溫馨提示作者的爬坑記錄,對你等大神完全沒有價值,別在我這浪費(fèi)生命溫馨提示續(xù)本文內(nèi)容簡單,發(fā)揚(yáng)了潛入潛出的精神,請謹(jǐn)慎浪費(fèi)時間溫馨提示再續(xù)魔卡少女櫻動畫再開撒花經(jīng)過前兩篇文章的梳理對象不完全探索記錄小伙子,你對象咋來的上篇對象不完全探索記 溫馨提示:作者的爬坑記錄,對你等大神完全沒有價值,別在我這浪費(fèi)生命溫馨提示-續(xù):本文內(nèi)容簡單,發(fā)揚(yáng)了潛入潛出的精神,請謹(jǐn)慎浪費(fèi)時間溫馨提示-再續(xù):《魔...
摘要:這是因?yàn)樽宇悰]有自己的對象,而是繼承父類的對象,然后對其進(jìn)行加工。 溫馨提示:作者的爬坑記錄,對你等大神完全沒有價值,別在我這浪費(fèi)生命溫馨提示-續(xù):你們要非得看,我也攔不住,但是至少得準(zhǔn)備個支持ES6的Chrome瀏覽器吧?溫馨提示-再續(xù):ES6簡直了,放著不用簡直令人發(fā)指! 書接上回,即便是程序員,也還是能夠通過自己的努力辛辛苦苦找到合適對象的,見前文《javascript對象不完全...
摘要:看著別人寫的功能對,就直接拿過來用,寫出來的代碼臃腫到爆炸,滿屏幕的的初級使用方式,運(yùn)氣好了能湊合跑起來,出了問題全臉懵逼,心中安慰自己一萬遍我可是干設(shè)計(jì)的,但是既然打算好好整下就得從頭開始看了。 溫馨提示:作者的爬坑記錄,對你等大神完全沒有價值,別在我這浪費(fèi)生命 首先,說實(shí)話,我對不起javascript,作為一個接觸前端快10年的老前端(偽),一直發(fā)揚(yáng)的是不求甚解的拿來就用主義???..
摘要:站在這個時間點(diǎn)上,我對自己之前三次失敗的面試經(jīng)歷做了一次深度回顧。關(guān)于我第三次面試失敗的經(jīng)歷,依然是與輪播圖有關(guān)。當(dāng)然,這次思特奇面試之旅,最后也是以失敗告終,這也是我離進(jìn)大廠最近的一次。 showImg(https://segmentfault.com/img/bVYQuP?w=528&h=513); 前言 時間的齒輪已經(jīng)來到了2017年的11月份,距離2018年僅僅還剩下不到兩...
閱讀 1020·2021-11-22 13:52
閱讀 1450·2021-11-19 09:40
閱讀 3184·2021-11-16 11:44
閱讀 1279·2021-11-15 11:39
閱讀 3913·2021-10-08 10:04
閱讀 5374·2021-09-22 14:57
閱讀 3108·2021-09-10 10:50
閱讀 3191·2021-08-17 10:13