js中常見繼承方式


1.原型模式

function Father(){
this.property = true;

}
Father.prototype.getValue = function(){

return this.property;
}
function Son(){
this.Sonproperty = false;
}
//繼承Father
Son.prototype = new Father();//原型重寫,contructor被改寫
Son.prototype.construtor = Son;//重新指向Son
Son.prototype.getSonValue = function(){
return this.property;
}
var instance = new Son();
console.log(instance.getValue());
/*缺點:
1.引用原型值會被所有實例共享
2.子類無法向父類傳參
*/
2.借用函數繼承(經典繼承)
 
//基本思想:在子類型構造函數中調用超類型的構造函數
function Father(){
this.colors = ["red","blue","green"];
name = "haha";
}

function Son(){
Father.call(this);//繼承Father,並向父類型傳參

}
Son.prototype = new Father;
var instance1 = new Son();
instance1.colors.push("black");
console.log(instance1.colors);

instance2 = new Son();
instance2.colors.push("pink");
console.log(instance2.colors);
/*
解決了原型鏈所存在的兩個問題
但是依然存在構造函數方法無法復用的問題
*/

3.組合繼承(偽經典繼承)---經常使用
 
// //集合原型和構造兩者之長
// //基本思想: 使用原型鏈實現對原型屬性和方法的繼承,通過借用構造函數來實現對實例屬性的繼承.
function Father(name){
this.name = name;
this.colors = ["red","pink","green"];
}

Father.prototype.sayname = function(){
console.log(this.name);
}

function Son(name,age){
Father.call(this,name);//使用構造函數進行實例屬性的繼承
this.age = age;
}

Son.prototype = new Father();//使用原型鏈繼承超類型方法
Son.prototype.constructor = Son;//重新指向Son
Son.prototype.sayage = function(){
console.log(this.age);
}

var instance1 = new Son("lisi",12);
instance1.colors.push("brown");
console.log(instance1.colors);
instance1.sayname();
instance1.sayage();

var instance2 = new Son("hah",22);
instance2.colors.push("black");
console.log(instance2.colors);
instance2.sayname();
instance2.sayage();

4.原型式繼承(淺拷貝)

//原型式繼承
/*基本思想:在object()函數內部, 先創建一個臨時性的構造函數,
然后將傳入的對象作為這個構造函數的原型,最后返回了這個臨時類型
的一個新實例.*/
var person = {
name : "van",
friends : ["hah","yisi"]
};
var anotherPerson = Object.create(person);
anotherPerson.friends.push("yixiu");
console.log(person.friends);
/*
和原型模式相同的是所有新對象依然共享含有引用類型值的屬性
*/
5.寄生式繼承
 
/*寄生式繼承的思路與(寄生)構造函數和工廠模式類似,
即創建一個僅用於封裝繼承過程的函數,該函數在內部以
某種方式來增強對象,最后再像真的是它做了所有工作一樣返回對象.*/
function createAnother(original){
var clone = Object.create(original);//先進行淺復制后增強對象
clone.sayhi = function(){//進行增強
console.log(1);
}
return clone;
}
var person = {
friends : ["hah","yisi"]
};
//缺點:無法進行函數復用,只能使用父類中的方法
// person.prototype.say = function(){
// console.log(2);
// }
var anotherPerson = createAnother(person);
anotherPerson.friends.push("yixiu");
console.log(person.friends);
anotherPerson.sayhi();
// anotherPerson.say();
6.寄生組合式繼承(結合前面的所有優點)
 
//寄生組合式繼承就是為了降低調用父類構造函數的開銷而出現的
//基本思路是: 不必為了指定子類型的原型而調用超類型的構造函數
function extend(subClass,superClass){
var F = function(){};
F.prototype = superClass.prototype;
//subClass.prototype =superClass.prtotype相當於原型共享而非繼承
subClass.prototype = new F();//繼承superClass的原型
subClass.prototype.constructor = subClass;//原型重寫,手動綁定

subClass.superclass = superClass.prototype;//將superClass.prototype緩存起來,方便后續訪問
if(superClass.prototype.constructor == Object.prototype.constructor){
superClass.prototype.constructor = superClass;
}
}
function Father(name){
this.name = name;
this.colors = ["red","pink","green"];
}

Father.prototype.sayname = function(){
console.log(this.name);
}

function Son(name,age){
Father.call(this,name);//使用構造函數進行實例屬性的繼承,調用第一次
this.age = age;
}

extend(Son,Father);//
Son.prototype.constructor = Son;//重新指向Son
Son.prototype.sayage = function(){
console.log(this.age);
}

var instance1 = new Son("lisi",12);
instance1.colors.push("brown");
console.log(instance1.colors);
instance1.sayname();
instance1.sayage();

var instance2 = new Son("hah",22);
instance2.colors.push("black");
console.log(instance2.colors);
instance2.sayname();
instance2.sayage();



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM