1.借用构造函数继承(call继承),私对私:
把父类当做普通函数执行,让其执行的时候,方法中的this变为子类的实例即可
缺点:只能继承 A 中的私有变量,不能继承原型上的方法
function A(){
this.x = 'x';
}
A.prototype.getX = function(){
console.log(this.x)
}
function B(){
A.call(this);
this.y = 'y'
this.getY = function(){
console.log(this.y)
}
}
let b = new B();
console.log(b)
2.原型继承:
公对公:将子类的原型指向父类的原型,但并没有继承其私有属性
缺点:并没有将父类的私有属性变成子类的私有属性。
function A(){
this.x = '1';
}
A.prototype.getX = function(){
console.log(this.x)
}
function B(){
this.y = 'y'
}
B.prototype = new A();//子类的原型指向父类的实例,因此子类也能访问到父类的私有属性,以及父类的原型方法
B.prototype.constructor = B;//原型上的构造函数应该也是它自己
B.prototype.getY = function getY() {
console.log(this.y);
};
let b = new B();
console.log(b);
3.组合继承
call继承+原型继承的组合
缺点:调用了两次父类的构造函数,并将父类的私有属性在子类里,和子类的原型里都放了一份。
function A(){
this.x = '1';
}
A.prototype.getX = function(){
console.log(this.x)
}
function B(){
A.call(this);
this.y = 'y'
}
B.prototype = new A();
B.prototype.getY = function getY() {
console.log(this.y);
};
let b = new B();
console.log(b);
4.寄生组合继承:相对于组合继承来说,不会再调用两次父类的构造函数
function superType(name){
this.name = name;
this.colors = ['red','blue'];
}
superType.prototype.jump = function(){
console.log('jump');
}
function subType(){
superType.call(this,'李锦涛')
this.age = 20
}
//通过创建一个新对象,并将新对象的原型指向父类的原型,再将子类的原型指向此对象,这样只继承了父类原型,并没有将父类的私有属性也添加到原型上
var obj = Object.create(superType.prototype);
obj.constructor = subType.constructor;
subType.prototype = obj;
subType.prototype.run = function(){
console.log('run');
}
let sub = new subType();
console.log(sub);