面向對象的繼承方式有三種:
? ? ? ?1、原型鏈實現(xiàn)繼承
//定義一個父類
function?Parent() {
this.pv="parent";
}
Parent.prototype.showParent=function() {
alert(this.pv);
}
//定義一個子類
function?Son() {
this.sv="Son";
}
//使用原型鏈來實現(xiàn)繼承
Son.prototype= new Parent();
Son.prototype.showSon=function() {
alert(this.sv);
}
var?s1= new Son();
s1.showParent();
s1.showSon();
但是這種方式存在一些問題:
1、無法從子類中調用父類的構造函數(shù)启搂, 這樣就沒有辦法把子類中屬性賦值給父類狈孔。
2岭妖、父類中屬性是在子類的原型中的箕速,這違背了我們前面所講的封裝的理念( 屬性在對
象中,方法在原型中)帖世, 會出現(xiàn)前面值的混淆問題。
? ? ? ? 2沸枯、基于偽裝實現(xiàn)繼承
//定義一個父類
function?Parent() {
this.pv="parent";
}
//定義一個子類
function?Son() {
this.sv="Son";
Parent.call(this);//注意:此時的this指的是Son的對象
//那么就是Son對象調用Parent函數(shù)
}
var?s1= new Son();
alert(s1.pv);
除了call方法外日矫,還可利用apply方法,兩者不同之處在于第二個參數(shù)绑榴,call是參數(shù)列表哪轿,而apply是參數(shù)數(shù)組。
這種方式可以解決原型鏈繼承所產生的問題翔怎,但同樣存在著其他問題:
由于使用偽造的方式繼承窃诉,子類的原型不會指向父類,所以父類中寫在原型中的方法不
會被子類繼承赤套, 所以子類調用不到父類的方法飘痛。
解決的辦法就是將父類的方法放到子類中來,但是這樣的又違背了封裝的理念容握。
? ? ? ? 3宣脉、基于組合實現(xiàn)繼承
function?Parent(name) {
this.name=name;
this.friends=["老許","老孫"];
}
Parent.prototype.parentSay=function() {
alert(this.name+"---->"+this.friends);
}
//定義一個子類
function?Son(name,age) {
this.age=age;
Parent.apply(this,[name]);
}
//使用原型鏈來實現(xiàn)繼承
Son.prototype= new Parent();
Son.prototype.sonSay=function() {
alert(this.name+"*******==="+this.age);
}
var?s1= newSon("老王",18);
s1.friends.push("老劉");
s1.parentSay();
s1.sonSay();
var?s2 = newSon("老李",28);
s2.parentSay();
s2.sonSay();
這種方法就可以同時解決以上兩個問題。
ECMAScript6—面向對象
ES6中利用class來申明類剔氏。
/**
*使用class關鍵字申明一個類脖旱,類名為Parent
*/
class?Parent {
//constructor方法就是Parent的構造方法
//可以使用它來初始化Parent類的屬性
constructor(name,age) {
this.name=name;
this.age=age;
}
//直接申明Parent類的方法,say
say() {
returnthis.name+"---->"+this.age;
}
//使用static關鍵字申明靜態(tài)方法
//注意靜態(tài)方法屬于類介蛉,而不屬于對象
static sayHello() {
alert("Hello老王");
}
}
//錯誤
//new Parent().sayHello();
//正確萌庆,該方法數(shù)據(jù)類
//Parent.sayHello();
在ES6中利用extend來實現(xiàn)繼承:
//使用extends來申明Son類繼承Parent類
class?Son extends Parent {
constructor(name,age,sex) {
//使用super關鍵字表示父類(超類)
super(name,age);
this.sex=sex;
}
sayWord() {
alert(this.sex+"----->"+this.name+"----------"+this.age);
}
//使用父類中的同名方法,會覆蓋父類方法(override)
say() {
return"哈哈";
}
}
let p1= new Son("阿里巴巴",15,"男");
//p1.sayWord();
alert(p1.say());