继承:子类继承父类的属性和方法,下面介绍js中继承的四种常用方法,原型继承,Call继承,寄生组合继承,ES6中类的继承
//定义父类,给父类添加属性x,和方法getX
function Father(x) {
this.x = x
}
Father.prototype.getX=function(){
console.log(this.x);
}
//定义子类,给子类添加属性y,和方法getY
function Child(y){
this.y = y
}
Child.prototype.getY=function(){
console.log(this.y)
}
//实例化子类,他能够访问的属性为y和getY;
let b = new Child(10);
console.log(b.y);
b.getY();
原型继承
让父类的属性和方法在子类实例的原型链上
function Father(x) {
this.x = x
}
Father.prototype.getX=function(){
console.log(this.x);
}
function Child(y){
this.y = y
}
Child.prototype = new Father(); //第一步,将父类放到子类原型链上
Child.prototype.constructor = Child; //第二步
Child.prototype.getY=function(){
//第三步,添加自己的私有方法
console.log(this.y)
}
var a = new Child(10)
console.dir(a)
原型继承的弊端:原型继承不是一个拷贝继承,而是通过原型链查找到父类的方法和属性。
子类可以重写父类上的方法,这样会导致父类的其他实例也会产生影响,但是一般不会去直接操作__proto__
Call继承
function Father(x) {
this.x = x
}
Father.prototype.getX=function(){
console.log(this.x);
}
function Child(y){
Father.call(this); //执行父类的构造函数,将this改为自身,相当于继承父类的私有属性
this.y = y
}
Child.prototype.getY=function(){
console.log(this.y)
}
var a = new Child(10)
console.dir(a)
上面的例子只提供了继承父类的私有属性,父类的公有属性没有继承
寄生组合继承
使用Call继承父类的私有属性,使用原型继承父类的共有属性
function Father(x) {
this.x = x
}
Father.prototype.getX=function(){
console.log(this.x);
}
function Child(y){
Father.call(this);
this.y = y
}
Child.prototype = Object.create(Father.prototype);
Child.prototype.getY=function(){
console.log(this.y)
}
Child.prototype.constructor = Child;
var a = new Child(10)
console.dir(a)
父类私有和共有属性是子类的私有和共有属性
class extends 继承
首先我们来看一下class定义一个类,class其实是一个语法糖,本质上还是函数,但是不能直接执行
class Father{
constructor(x){
this.x = x
}
getX(){
console.log(this.x);
}
}
var a = new Father();
console.dir(a);
和我们用prototype写方法是一样的效果
class Father{
constructor(x){
this.x = x
}
getX(){
console.log(this.x);
}
}
class Child extends Father{
//extends
constructor(y){
super(100); //super
this.y = y;
}
getY(){
console.log(y)
}
}
var a = new Child(10)
console.dir(a)
但是最后的结果可以看到,父类的私有属性变为了子类实例的私有属性,父类的公有方法放到的子类实例的原型上。所以ES6中的继承原理就是寄生组合继承。但是要求遵守语法,在子类的constructor中的第一行必须是super();