1原型继承:子类的原型指向父类的一个实例
//父类
function Person() {
this.name = "周乃康";
}
Person.prototype.getName = function getName() {
console.log(this.name);
};
//子类
function Boy() {
this.bname = '周星星';
}
Boy.prototype.getbName = function getbName() {
console.log(this.y);
};
//Boy子类 => Person父类,让子类Boy的原型指向父类Person的实例
Boy.prototype = new Person;
let boy = new Boy;
console.dir(Boy);
通过B.prototype = new A这一句话达成继承。
js中的面向对象的机制都是基于原型链完成的,所以js中的继承也可以是基于原型链的,但这其中又有很多弊端。
2 call继承
//父类
function Person() {
this.name = "周乃康";
}
Person.prototype.getName = function getName() {
console.log(this.name);
};
//子类
function Boy() {
Person.call(this);// ◆◆◆◆◆
this.bname = "周星星";
}
Boy.prototype.getbName = function getbName() {
console.log(this.bname);
};
let boy = new Boy;
console.log(boy);
boy.getbName();//打印周星星
call继承只能继承父类中的私有属性(继承的私有属性赋值给子类实例的私有属性),而且是类似拷贝过来一份,不是链式查找;因为只是把父类当做普通的方法执行,所以父类原型上的公有属性方法无法被继承过来。
3寄生组合继承:call继承 + 变异版的原型继承共同完成
//父类
function Person() {
this.name = "周定发";
}
Person.prototype.getName = function getName() {
console.log(this.name);
};
//子类
function Boy() {
Person.call(this);
this.bname = "周星星";
}
//=>Object.create(OBJ) 创建一个空对象,让其__proto__指向OBJ(把OBJ作为空对象的原型)
Boy.prototype = Object.create(Person.prototype);
Boy.prototype.constructor = Boy; //把constructor补上
Boy.prototype.getbName = function getbName() {
console.log(this.bname);
};
let boy = new Boy;
console.log(boy);
利用了call继承实现私有到私有,利用原型继承实现了公有到公有。
4 ES6中的class类继承(语法糖)
class Person {
constructor() {
this.name = "周定发";
}
getName() {
console.log(this.name);
}
}
//=>extends继承和寄生组合继承基本类似
class Boy extends Person {
constructor() {
//=>一但使用extends实现继承,只要自己写了constructor,就必须写super
super();
this.bname = "周星星";
}
getbName() {
console.log(this.bname);
}
}
let boy = new Boy;
console.log(boy);
其实extends继承和寄生组合继承基本类似,而且必须加上super()函数,它相当于A.call(this)。