1.原型鏈繼承:
functionBook (name,author){
this.name=name;
this.author=author;
}
Book.prototype.tell=function(){console.log("Book:"+this.name+"?Author:"+this.author);};
functionJavaScript(){}
JavaScript.prototype=newBook("JavaScript","Nicholas");
varjs1=newJavaScript();
varjs2=newJavaScript();
js1.tell();
js2.tell();
可以發(fā)現(xiàn),原型鏈繼承有一個問題然遏,那就是父類中的私有屬性播玖,會因為父類作為子類原型構(gòu)建原型鏈颜曾,使得子類所有實例所共享往枷。當(dāng)我們通過一個實例修改共享屬性時更耻,其他實例也將受到影響:
functionBook (name,author){
this.name=name;
this.author=[author];
}
Book.prototype.tell=function(){console.log("Book:"+this.name+"?Author:"+this.author);};
functionJavaScript(){}
JavaScript.prototype=newBook("JavaScript","Nicholas");
varjs1=newJavaScript();
varjs2=newJavaScript();
js1.author.push("C.Zakas");
js2.tell();
但是當(dāng)你直接為實例中屬性賦值時自沧,是在實例中重新定義了一個對應(yīng)屬性纵柿,而不是在修改原型中屬性:
functionBook (name,author){
this.name=name;
this.author=author;
}
Book.prototype.tell=function(){console.log("Book:"+this.name+"?Author:"+this.author);};
functionJavaScript(){}
JavaScript.prototype=newBook("JavaScript","Nicholas");
varjs1=newJavaScript();
varjs2=newJavaScript();
js1.author="C.Zakas";
//并不是js1沒有影響js2,而是在js1中創(chuàng)建了新author屬性
console.log(js1.hasOwnProperty("author"));//true
console.log(js2.hasOwnProperty("author"));//false
js1.tell();//Book:JavaScript?Author:C.Zakas
js2.tell()
2.構(gòu)造函數(shù)繼承:
functionBook?(name,author){
this.name=name;
this.author=author;
}
Book.prototype.tell=function(){console.log("Book:"+this.name+"?Author:"+this.author);};
functionJavaScript(){
Book.apply(this,arguments);
}
varjs1=newJavaScript("JavaScript","Nicholas");
varjs2=newJavaScript("JavaScriopt","C.Zakas");
console.log("js1:"+js1.author+"?js2:"+js2.author);//js1:Nicholas?js2:C.Zakas
js1.tell();//Uncaught?TypeError:?js1.tell?is?not?a?function
js2.tell();//Uncaught?TypeError:?js2.tell?is?not?a?function
構(gòu)造函數(shù)繼承衩茸,可以使每個子類實例有一份自己的屬性芹血,但是無法找到父類原型中的函數(shù)。
3.組合繼承:
functionBook (name,author){
this.name=name;
this.author=author;
}
Book.prototype.tell=function(){console.log("Book:"+this.name+"?Author:"+this.author);};
functionJavaScript(){
Book.apply(this,arguments);
}
JavaScript.prototype=newBook();
varjs1=newJavaScript("JavaScript","Nicholas");
varjs2=newJavaScript("JavaScriopt","C.Zakas");
console.log("js1:"+js1.author+"?js2:"+js2.author);//js1:Nicholas?js2:C.Zakas
js1.tell();//Book:JavaScript?Author:Nicholas
js2.tell();
組合繼承使得每個子類實例楞慈,既可以保存一份自己的屬性幔烛,又可以共享同一個函數(shù)。
4.寄生組合繼承:
functionBook (name,author){
this.name=name;
this.author=author;
}
Book.prototype.tell=function(){console.log("Book:"+this.name+"?Author:"+this.author);};
functionJavaScript(){
Book.apply(this,arguments);
}
JavaScript.prototype=Object.create(Book.prototype);
JavaScript.prototype.constructor=JavaScript;
varjs1=newJavaScript("JavaScript","Nicholas");
varjs2=newJavaScript("JavaScriopt","C.Zakas");
console.log("js1:"+js1.author+"?js2:"+js2.author);//js1:Nicholas?js2:C.Zakas
js1.tell()囊蓝;
js2.tell();
console.log(js1.tell===js2.tell);