摘要:寄生組合式繼承的繼承方式有多種主要有原型鏈繼承借用構(gòu)造函數(shù)組合式繼承寄生式繼承和寄生組合式繼承。中利用定義類,實(shí)現(xiàn)類的繼承子類里調(diào)用父類構(gòu)造函數(shù)實(shí)現(xiàn)實(shí)例屬性和方法的繼承子類原型繼承父類原型,實(shí)現(xiàn)原型對象上方法的繼承。
JavaScript中實(shí)現(xiàn)繼承
??在JavaScript中實(shí)現(xiàn)繼承主要實(shí)現(xiàn)以下兩方面的屬性和方法的繼承,這兩方面相互互補(bǔ),既有共享的屬性和方法,又有特有的屬性和方法。
實(shí)例屬性和方法的繼承:
目的:每個實(shí)例都有自己特有的屬性和方法。特別是引用類型屬性,如果被共享,所有實(shí)例都可修改引用類型屬性,并且反應(yīng)到所有實(shí)例中。
原型屬性和方法的繼承:
目的:在繼承中實(shí)現(xiàn)屬性和方法的共享。避免每創(chuàng)建一次實(shí)例,都要新建一次屬性和方法。
??ES5的繼承方式有多種:主要有原型鏈繼承、借用構(gòu)造函數(shù)、組合式繼承、寄生式繼承和寄生組合式繼承。寄生組合式繼承集組合式繼承和寄生式繼承的優(yōu)點(diǎn)于一身,是ES5中,基于類型繼承的最有效方式。
??接下來基于寄生組合式繼承對ES5實(shí)現(xiàn)繼承的方面進(jìn)行解釋。
//父類 function SuperType(name){ //父類實(shí)例屬性 this.name = name; this.colors = ["red", "blue", "green"]; } //父類原型方法 SuperType.prototype.sayName = function(){ alert(this.name); }; //子類 function SubType(name, age){ SuperType.call(this, name);//1.借用構(gòu)造函數(shù):繼承父類的實(shí)例屬性; this.age = age; } //2.寄生式繼承:將父類原型的副本強(qiáng)制賦值給子類原型,實(shí)現(xiàn)繼承父類的原型方法。 inheritPrototype(SubType, SuperType); SubType.prototype.sayAge = function(){ alert(this.age); }; function inheritPrototype(subType, superType){ var prototype = object(superType.prototype); //創(chuàng)建父類原型的副本 prototype.constructor = subType; //將該副本的constructor屬性指向子類 subType.prototype = prototype; //將子類的原型屬性指向副本 }
??以上示例就是ES5中寄生組合式繼承的一個例子,如何實(shí)現(xiàn)子類繼承父類?
借用構(gòu)造函數(shù)SuperType.call(this, name);:當(dāng)new SubType()創(chuàng)建子類實(shí)例時,首先調(diào)用父類構(gòu)造函數(shù),實(shí)現(xiàn)了子類實(shí)例繼承父類的實(shí)例屬性和方法;
寄生式繼承inheritPrototype(SubType, SuperType);:將父類原型副本強(qiáng)制替換成子類原型(1.副本constructor指向子類;2.子類prototype指向副本),使得子類原型包含父類原型中的所有屬性和方法,實(shí)現(xiàn)了原型屬性和方法的繼承。
ES6中Class繼承??ES5中通過函數(shù)創(chuàng)建類型并基于原型實(shí)現(xiàn)繼承的方式與其他面向?qū)ο蟮恼Z言相比確實(shí)比較另類,沒有那么簡單明了;ES6就提供了更加接近傳統(tǒng)語言的寫法,引入了類的概念。
通過class關(guān)鍵字定義類class super{ constructor(name,color){ this.name=name; this.color=["red","blue","green"]; } sayName(){ alert(this.name); } }
1. constructor為構(gòu)造函數(shù),如果非顯示創(chuàng)建構(gòu)造函數(shù),定義類時也會自動創(chuàng)建構(gòu)造函數(shù); 2. 通過`this`定義的屬性和方法屬于實(shí)例屬性和方法;否則都是定義在原型上的屬性和方法; 3. class類中定義的方法`constructor、sayName`都屬于原型方法。extends實(shí)現(xiàn)類的繼承
class Person{ constructor(name,color){ this.name=name; this.color=["red","blue","green"]; } sayName(){ alert(this.name); } } class Student extends Person(){ constructor(name,color,score){ super(name,color);//調(diào)用父類構(gòu)造函數(shù),this指向子類 this.score=score; } showScore(){ alert(this.score); } } let stu1=new Student("xuxu",["white","black","pink"],90); stu1.sayName();//"xuxu" stu1.showScore();//90
1. 子類構(gòu)造函數(shù)中調(diào)用父類構(gòu)造函數(shù),實(shí)現(xiàn)了子類繼承父類的實(shí)例屬性和方法; 2. 通過extends,子類原型繼承父類原型上的屬性和方法: - Student.__proto__=Person;//作為對象,子類原型等于父類(構(gòu)造函數(shù)的繼承) - Student.prototype.__proto__=Person.prototype;//作為構(gòu)造函數(shù),子類原型對象是父類原型對象的實(shí)例。 3. 子類靜態(tài)方法繼承父類靜態(tài)方法 - 靜態(tài)方法的定義:關(guān)鍵字static; - 調(diào)用方法:類名調(diào)用(而不是實(shí)例調(diào)用); - 普通方法中,super作對象表示父類原型(用來調(diào)用父類原型方法); 靜態(tài)方法中super作對象表示父類(用來調(diào)用父類靜態(tài)方法)。 - 普通方法中this指向?qū)嵗龑ο螅混o態(tài)方法中hits指向當(dāng)前子類。prototype和__proto__相互關(guān)系
對象(實(shí)例和原型對象)有__proto__屬性,構(gòu)造函數(shù)有prototype屬性,原型對象有constructor屬性。
??假設(shè)class B extends A,實(shí)例對象分別是insB、insA:
A.prototype.constructor=A;//類的原型的構(gòu)造函數(shù)指向類本身。
insA.__proto__=A.prototype;//類的實(shí)例的原型指向創(chuàng)建它的構(gòu)造函數(shù)的原型。
B.__proto__=A;//作為對象,子類的原型等于父類
B.prototype.__proto__=A.prototype;//作為構(gòu)造函數(shù)子類原型繼承父類原型
insB.__proto__.__proto__=insA.__proto__;//子類實(shí)例的原型的原型指向父類實(shí)例的原型
總結(jié)
ES5中:
利用借用構(gòu)造函數(shù)實(shí)現(xiàn) 實(shí)例屬性和方法的繼承 ;
利用原型鏈或者寄生式繼承實(shí)現(xiàn) 共享的原型屬性和方法的繼承 。
ES6中:
利用class定義類,extends實(shí)現(xiàn)類的繼承;
子類constructor里調(diào)用super()(父類構(gòu)造函數(shù))實(shí)現(xiàn) 實(shí)例屬性和方法的繼承;
子類原型繼承父類原型,實(shí)現(xiàn) 原型對象上方法的繼承。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/108117.html
摘要:今天閑來無事,看見幾行小字。又說所有對象,繼承終是。強(qiáng)行押韻一波這首詩的意思就是說的我今天沒有什么事情,然后無意中又在網(wǎng)上看到了任何對象都是從對象繼承而來的這句話。一時興起,便去驗(yàn)證這句話。 今天閑來無事,看見幾行小字。又說所有對象,繼承終是Obj?!?強(qiáng)行押韻一波 這首詩的意思就是說的我今天沒有什么事情,然后無意中又在網(wǎng)上看到了任何對象都是從Object對象繼承而來的這句話。一時興...
摘要:語法在中運(yùn)行以下代碼調(diào)試觀察的值。以上的繼承其實(shí)就是我們說的寄生式組合繼承,也是中最常用的繼承模式。 在es6中,新增了class關(guān)鍵字用于定義一個類,但是本質(zhì)上并沒有給javascript增加新的oop機(jī)制,因?yàn)閖avascript原型繼承以及構(gòu)造函數(shù)式聲明使人感到晦澀難懂,添加class的目的就是為了掩蓋它底層的機(jī)制,使得我們不用直接接觸這些概念,相當(dāng)于一個語法糖。 class語法...
摘要:在掘金上看到了一位大佬發(fā)了一篇很詳細(xì)的面試記錄文章一年半經(jīng)驗(yàn),百度有贊阿里面試總結(jié),為了查漏補(bǔ)缺,抽空就詳細(xì)做了下。 在掘金上看到了一位大佬發(fā)了一篇很詳細(xì)的面試記錄文章-《一年半經(jīng)驗(yàn),百度、有贊、阿里面試總結(jié)》,為了查漏補(bǔ)缺,抽空就詳細(xì)做了下。(估計(jì)只有我這么無聊了哈哈哈) 有給出的或者有些不完善的答案,也盡力給出/完善了(可能有錯,大家自行辨別)。有些很困難的題目(例如實(shí)現(xiàn)Promi...
摘要:在掘金上看到了一位大佬發(fā)了一篇很詳細(xì)的面試記錄文章一年半經(jīng)驗(yàn),百度有贊阿里面試總結(jié),為了查漏補(bǔ)缺,抽空就詳細(xì)做了下。 在掘金上看到了一位大佬發(fā)了一篇很詳細(xì)的面試記錄文章-《一年半經(jīng)驗(yàn),百度、有贊、阿里面試總結(jié)》,為了查漏補(bǔ)缺,抽空就詳細(xì)做了下。(估計(jì)只有我這么無聊了哈哈哈) 有給出的或者有些不完善的答案,也盡力給出/完善了(可能有錯,大家自行辨別)。有些很困難的題目(例如實(shí)現(xiàn)Promi...
摘要:繼承的繼承可以簡單的認(rèn)為就是上篇文章中的寄生組合繼承模型幾乎一模一樣,只是在語法結(jié)構(gòu)上多了和關(guān)鍵字,另外一個區(qū)別就是父類和子類通過連接。 ES5繼承 VS ES6繼承 前言 ES6 已經(jīng)發(fā)展了很長時間里 javascript相對于其他例如java等是一門比較怪異的語言, 由于其歷史原因其繼承機(jī)制和對象生成方式被人詬病. ES6 的出現(xiàn)將徹底改變這一現(xiàn)狀, ES6 引入了新的生成對象(類...
閱讀 3067·2021-09-22 15:59
閱讀 1319·2021-08-30 09:46
閱讀 2281·2019-08-30 15:54
閱讀 2020·2019-08-26 12:15
閱讀 2547·2019-08-26 12:09
閱讀 1346·2019-08-26 11:57
閱讀 3343·2019-08-23 17:11
閱讀 1892·2019-08-23 15:59