JS中的四大继承方案

 
所谓继承,就是子类继承父类中的属性和方法。
 
 
方案一:原型继承
 
方法:子类的原型指向父类的一个实例。
function A() {
    this.x = 100;
}
A.prototype.getX = function getX() {
    console.log(this.x);
};

function B() {
    this.y = 200;
}
B.prototype.sum=function(){}
B.prototype = new A; //B子类 => A父类,让子类B的原型指向父类A的实例

B.prototype.getY = function getY() {
    console.log(this.y);
};
let b = new B;

 

JS中的四大继承方案_第1张图片

 

 

 

通过B.prototype = new A这一句话达成继承。

 

js中的面向对象的机制都是基于原型链完成的,所以js中的继承也可以是基于原型链的,但这其中又有很多弊端。

比如B之前的原型B.prototype上的方法b已经查找不到,b的constructor应该是B,但现在是A,b可以通过b.__proto__或b.__proto__.__proto__肆意修改父类上的属性和方法,而父类上不管私有还是公有的属性和方法都会成为子类公有的,这些种种问题都是需要注意的,这大概就是IE浏览器禁止使用__proto__的原因吧。

 

 
方案二:call继承
 
方法:把父类当做普通函数执行,让其执行的时候,方法中的this变为子类的实例即可。
function A() {
    this.x = 100;
}
A.prototype.getX = function getX() {
    console.log(this.x);
};

function B() {
    //call继承
    A.call(this);  //=>this.x = 100; => b.x=100;
    this.y = 200;
}
B.prototype.getY = function getY() {
    console.log(this.y);
};
let b = new B;

 

JS中的四大继承方案_第2张图片

 

 

call继承只能继承父类中的私有属性(继承的私有属性赋值给子类实例的私有属性),而且是类似拷贝过来一份,不是链式查找;因为只是把父类当做普通的方法执行,所以父类原型上的公有属性方法无法被继承过来。
 
 
方案三:寄生组合继承
 
方法:call继承+变异版的原型继承共同完成的。
function A() {
    this.x = 100;
}
A.prototype.getX = function getX() {
    console.log(this.x);
};

function B() {
    A.call(this);
    this.y = 200;
}
//=>Object.create(OBJ) 创建一个空对象,让其__proto__指向OBJ(把OBJ作为空对象的原型)
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B; //把constructor补上
B.prototype.getY = function getY() {
    console.log(this.y);
};
let b = new B;
console.log(b);

 

JS中的四大继承方案_第3张图片

 

 

 
这个方案利用了call继承实现私有到私有,利用原型继承实现了公有到公有,当然还是原型继承的一些弊端应该注意。
 
 
方案四:ES6中class类
 
class A {
    constructor() {
        this.x = 100;
    }
    getX() {
        console.log(this.x);
    }
}
//=>extends继承和寄生组合继承基本类似
class B extends A {
    constructor() {
        super(); //=>一但使用extends实现继承,只要自己写了constructor,就必须写super
        this.y = 200;
    }
    getY() {
        console.log(this.y);
    }
}

let b = new B;

 

JS中的四大继承方案_第4张图片

 

 

 
其实extends继承和寄生组合继承基本类似,而且必须加上super()函数,它相当于A.call(this)。
 
项目中我们会用到继承地方比如自己写插件或者类库的时候,还有就是react中用class实现继承。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

你可能感兴趣的:(JS中的四大继承方案)