JavaScript也是可以“繼承”的!
各位看官或是好奇,或是一知半解。什么是prototype,__proto__,constructor、哪種繼承方式好。今天就在這交流交流。
什么是prototype,__proto__,constructor
https://blog.csdn.net/cc18868876837/article/details/81211729
<https://blog.csdn.net/cc18868876837/article/details/81211729>?(
尊重原作者,這是篇超級(jí)好的文章,一定要點(diǎn)進(jìn)去細(xì)細(xì)研讀)
上面文章已經(jīng)講的很明白了,最后對(duì)文章總結(jié)再解釋一下
?
?
第一點(diǎn)主要強(qiáng)調(diào),我們拿到一個(gè)對(duì)象,主要看它什么,因?yàn)镴avaScript中一切都是對(duì)象,所以在理解的時(shí)候很容易因?yàn)樗衅渌兞恳不煜?,所以我們研究一個(gè)對(duì)象,首先要確定我們的目標(biāo)是什么,如果目標(biāo)是對(duì)象,則抓住__proto__和constructor屬性,如果目標(biāo)是函數(shù)則抓住prototype屬性,這樣才能快速找到自己想要的東西解決問題。
第2,3,4點(diǎn)是關(guān)于哪種繼承方式好的關(guān)鍵,一定要弄懂,下面再解釋一下new關(guān)鍵詞做了什么(沒準(zhǔn)你不懂上面文章寫的,看懂我的例子)。
?
new關(guān)鍵詞做了什么
1 //例如 2 var child = new Parent(); 3 4 //上面這句代碼就等于下面三句 5 var child = {}; 6
child.__proto__ = Parent.prototype; 7 Parent.call(child);
咳咳,就跟教育孩子一樣,孩子出生是張白紙(var child = {}),然后繼承
了父母的一些行為(就是方法),例如怎么說話啊,喜歡吃什么啊(child.__proto__ =
Parent.prototype;),最后得到父母的一些人生經(jīng)驗(yàn),就是復(fù)制了屬性變量(Parent.call(child))。
這里需要注意,孩子是不能生孩子的,即
var child2 = new child()
絕對(duì)報(bào)錯(cuò)的,對(duì)象是對(duì)象,并不是函數(shù),也不會(huì)變成函數(shù)。
?哪種繼承方式好
繼承能夠代碼復(fù)用,能讓邏輯更清晰,所以是很有必要的,那怎么樣繼承效果最好呢
https://www.cnblogs.com/humin/p/4556820.html#
<https://www.cnblogs.com/humin/p/4556820.html#>(尊重原作者,這是篇超級(jí)好的文章,一定要點(diǎn)進(jìn)去細(xì)細(xì)研讀
,這話好像有點(diǎn)熟悉)
推薦給大家一個(gè)方法,打開谷歌瀏覽器,按F12,在里面可以進(jìn)行簡(jiǎn)單的練習(xí)
文章最好從第一個(gè)繼承開始,就自己動(dòng)手模擬一下,看看變量的__proto__和prototype到底指什么
而且從第一個(gè)繼承方法演變到最完美的一個(gè),這個(gè)思考過程是十分重要的。
我來再解釋一下最完美的繼承模式:寄生組合繼承
1 function Cat(name){ 2 Animal.call(this); 3 this.name = name || 'Tom'; 4 }
5 (function(){ 6 // 創(chuàng)建一個(gè)沒有實(shí)例方法的類 7 var Super = function(){}; 8
Super.prototype = Animal.prototype; 9 //將實(shí)例作為子類的原型 10 Cat.prototype = new
Super();11 })(); 12 13 // Test Code 14 var cat = new Cat(); 15
console.log(cat.name);16 console.log(cat.sleep()); 17 console.log(cat instanceof
Animal);// true 18 console.log(cat instanceof Cat); //true 19 20 感謝 @bluedrink
提醒,該實(shí)現(xiàn)沒有修復(fù)constructor。21 22 Cat.prototype.constructor = Cat; // 需要修復(fù)下構(gòu)造函數(shù)
第7-10行的代碼為什么這樣做
通過寄生方式,砍掉父類的實(shí)例屬性,這樣,在調(diào)用兩次父類的構(gòu)造的時(shí)候,就不會(huì)初始化兩次實(shí)例方法/屬性,避免的組合繼承的缺點(diǎn)?這句話什么意思
回到剛才對(duì)new的解釋,假設(shè)如組合5:組合繼承一樣
1 function Cat(name){ 2 Animal.call(this); 3 this.name = name || 'Tom'; 4 } 5
Cat.prototype =new Animal();
第5行代碼相當(dāng)于:
Cat.prototype = {}
Cat.prototype.__proto__ = Animal.prototype
Animal.call(Cat.prototype) //這一步是多余的并不需要
所以 var Super = function(){}; 一個(gè)空方法來代替,因?yàn)橹恍枰?br>
Cat.prototype.__proto__ = Animal.prototype 就可以了 而現(xiàn)在Super.prototype =
Animal.prototype 因此這個(gè)方法是最完美的
?
以上就是本次內(nèi)容的分享,感謝各位老哥的閱讀
?
熱門工具 換一換