js实现继承

原创
2020/10/09 14:59
阅读数 4.4K

es6之前的作法:

方法一:原型链   (与java的类多层继承思想类似,python可以多重继承,MixIn是常用的设计思想)
缺点:  当父级的属性有引用类型的时候,任意一个实例修改了这个属性,其他实例都会受影响

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   

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"

方法三:组合继承
缺点: 父类的构造器被调用了两次

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"

方法五:寄生组合式继承
改进组合继承,利用寄生式继承的思想继承原型

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继承

  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


 

展开阅读全文
打赏
1
5 收藏
分享
加载中
更多评论
打赏
0 评论
5 收藏
1
分享
返回顶部
顶部