js實現繼承

es6以前的做法:javascript

方法一:原型鏈   (與java的類多層繼承思想相似,python能夠多重繼承,MixIn是經常使用的設計思想)
缺點:  當父級的屬性有引用類型的時候,任意一個實例修改了這個屬性,其餘實例都會受影響java

function SuperType() {
  this.property = true;
}
SuperType.prototype.getSuperValue = function() {
  return this.property;
}
function subType() {
  this.property = false;
}

//繼承了SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){
  return this.property;
}

var instance = new SubType();
console.log(instance.getSuperValue());//true

方法二:借用構造函數
缺點:建立多個實例 , 父類的方法會被建立屢次。instance1.colors == intance2.colors  // false   python

function SuperType(){
 this.colors = ["red","blue","green"];
}

function SubType(){
  SuperType.call(this);//繼承了SuperType
}

var instance1 = new SubType();
instance1.colors.push("black");
console.log(instance1.colors);//"red","blue","green","black"
var instance2 = new SubType();
console.log(instance2.colors);//"red","blue","green"

方法三:組合繼承
缺點: 父類的構造器被調用了兩次es6

function SuperType(name) {
this.name = name;
this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function() {
console.log(this.name);
}
function SubType(name, age) {
SuperType.call(this,name);//繼承屬性
this.age = age;
}
//繼承方法
SubType.prototype = new SuperType();
Subtype.prototype.constructor = Subtype;
Subtype.prototype.sayAge = function() {
console.log(this.age);
}
var instance1 = new SubType("EvanChen",18);
instance1.colors.push("black");
consol.log(instance1.colors);//"red","blue","green","black"
instance1.sayName();//"EvanChen"
instance1.sayAge();//18
var instance2 = new SubType("EvanChen666",20);
console.log(instance2.colors);//"red","blue","green"
instance2.sayName();//"EvanChen666"
instance2.sayAge();//20

方法四:原型式繼承
用一個函數包裝一個對象,而後返回這個函數的調用,這個函數就變成了個能夠隨意增添屬性的實例或對象,結果是將子對象的__proto__指向父對象
缺點:共享引用類型  (相互影響)函數

function object(o) {
    function F(){}
    F.prototype = o;
    return new F();
}


//示例
var person = {
  name:"EvanChen",
  friends:["Shelby","Court","Van"];
};

var anotherPerson = Object.create(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");

var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie"

方法五:寄生組合式繼承
改進組合繼承,利用寄生式繼承的思想繼承原型this

function inheritPrototype(subType, superType){
    var protoType = Object.create(superType.prototype);    //建立對象
    protoType.constructor = subType;                    //加強對象
    subType.prototype = protoType;                        //指定對象
}
function SuperType(name){
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
    alert(this.name);
}

function SubType(name, age){
    SuperType.call(this, name);  
    
    this.age = age;
}

inheritPrototype(SubType, SuperType)

SubType.prototype.sayAge = function(){
    alert(this.age);
}

var instance = new SubType("Bob", 18);
instance.sayName();
instance.sayAge();

 

 

==== Es6 class繼承spa

  1. 繼承中,若是實例化子類輸出一個方法,先看子類有沒有這個方法,若是有就先執行子類的
  2. 繼承中,若是子類裏面沒有,就去查找父類有沒有這個方法,若是有,就執行父類的這個方法(就近原則)
  3. 若是子類想要繼承父類的方法,同時在本身內部擴展本身的方法,利用super 調用父類的構造函數,super 必須在子類this以前調用
// 父類有加法方法
        class Father{
            constructor(x,y) {
                this.x = x ;
                this.y = y ;
            }
            sum() {
                console.log(this.x + this.y);
            }
        }
        // 子類繼承父類加法的方法, 同時 擴展減法方法
        class Son extends Father {
            constructor (x,y){
                // 利用super調用父類的構造函數
                // super必須在子類this以前調用
                super(x,y);
                this.x = x;
                this.y = y;
            }
            subtract(){
                console.log(this.x - this.y);
            }
        }
        var son = new Son(20,10);
        son.subtract();//10
        son.sum(); //30
相關文章
相關標籤/搜索