JavaScript也是可以“繼承”的! 各位看官或是好奇,或是一知半解。什麼是prototype,__proto__,constructor、哪種繼承方式好。今天就在這交流交流。 什麼是prototype,__proto__,constructor https://blog.csdn.net/cc ...
JavaScript也是可以“繼承”的!
各位看官或是好奇,或是一知半解。什麼是prototype,__proto__,constructor、哪種繼承方式好。今天就在這交流交流。
什麼是prototype,__proto__,constructor
https://blog.csdn.net/cc18868876837/article/details/81211729 (尊重原作者,這是篇超級好的文章,一定要點進去細細研讀)
上面文章已經講的很明白了,最後對文章總結再解釋一下
第一點主要強調,我們拿到一個對象,主要看它什麼,因為JavaScript中一切都是對象,所以在理解的時候很容易因為它有其他變數也混淆,所以我們研究一個對象,首先要確定我們的目標是什麼,如果目標是對象,則抓住__proto__和constructor屬性,如果目標是函數則抓住prototype屬性,這樣才能快速找到自己想要的東西解決問題。
第2,3,4點是關於哪種繼承方式好的關鍵,一定要弄懂,下麵再解釋一下new關鍵詞做了什麼(沒準你不懂上面文章寫的,看懂我的例子)。
new關鍵詞做了什麼
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;),最後得到父母的一些人生經驗,就是複製了屬性變數(Parent.call(child))。
這裡需要註意,孩子是不能生孩子的,即
var child2 = new child()
絕對報錯的,對象是對象,並不是函數,也不會變成函數。
哪種繼承方式好
繼承能夠代碼復用,能讓邏輯更清晰,所以是很有必要的,那怎麼樣繼承效果最好呢
https://www.cnblogs.com/humin/p/4556820.html#(尊重原作者,這是篇超級好的文章,一定要點進去細細研讀,這話好像有點熟悉)
推薦給大家一個方法,打開谷歌瀏覽器,按F12,在裡面可以進行簡單的練習
文章最好從第一個繼承開始,就自己動手模擬一下,看看變數的__proto__和prototype到底指什麼
而且從第一個繼承方法演變到最完美的一個,這個思考過程是十分重要的。
我來再解釋一下最完美的繼承模式:寄生組合繼承
1 function Cat(name){ 2 Animal.call(this); 3 this.name = name || 'Tom'; 4 } 5 (function(){ 6 // 創建一個沒有實例方法的類 7 var Super = function(){}; 8 Super.prototype = Animal.prototype; 9 //將實例作為子類的原型 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 提醒,該實現沒有修複constructor。 21 22 Cat.prototype.constructor = Cat; // 需要修複下構造函數
第7-10行的代碼為什麼這樣做
通過寄生方式,砍掉父類的實例屬性,這樣,在調用兩次父類的構造的時候,就不會初始化兩次實例方法/屬性,避免的組合繼承的缺點 這句話什麼意思
回到剛纔對new的解釋,假設如組合5:組合繼承一樣
1 function Cat(name){ 2 Animal.call(this); 3 this.name = name || 'Tom'; 4 } 5 Cat.prototype = new Animal();
第5行代碼相當於:
Cat.prototype = {}
Cat.prototype.__proto__ = Animal.prototype
Animal.call(Cat.prototype) //這一步是多餘的並不需要
所以 var Super = function(){}; 一個空方法來代替,因為只需要
Cat.prototype.__proto__ = Animal.prototype 就可以了
而現在Super.prototype = Animal.prototype 因此這個方法是最完美的
以上就是本次內容的分享,感謝各位老哥的閱讀