ES6之类的继承

28 阅读1分钟

ES6之类的继承

先看之前的写法:

function Animal(type, name){
    this.type=type;
    this.name=name;
}
Animal.prototype.print=function(){
    console.log(`【种类】:${this.type}`);
    console.log(`【名字】:${this.name}`);
}
function Dog(name){
    //重新指向this,将父类的属性放到子类中
    Animal.call(this, "犬类", name);
}
Object.setPrototypeOf(Dog.prototype,Animal.prototype)
const dog=new Dog();
dog.print();
console.log(dog)

A继承B的意思是A在B的范围内,可以说A是B的子类,也可以说B派生A。上面的例子是通过call方法调用重新指定this,将父类参数形成的对象放到子类中,同时,还需要绑定子类的隐式原型到父类中,完成闭环。 现在的写法:

class Animal {
    constructor(type, name) {
        this.type = type;
        this.name = name;
    }
    print() {
        console.log(`【种类】:${this.type}`);
        console.log(`【名字】:${this.name}`);
    }
}
class Dog extends Animal {
    constructor(name) {
        super("犬类", name);
    }
}
const dog = new Dog("旺财");
dog.print();
console.log(dog);

现在我们可以直接使用 extends 表示继承关系,同时当子类中出现了 constructor 时,必须使用 super() 调用父类的构造函数,并且可以往里面传入参数。如果不写构造器的话,会自动加入一个构造器,并且使用与父类相同的构造器,相同的参数类型。
如果父类和子类有相同的原型方法,会在原型链上查找。首先会找到子类里的方法。

print()
{
        //当作对象里使用,super代表父类原型
        super.print();
        console.log(`【爱好】:${this.loves}`);
}

如果是作为对象使用,super 代表父类的原型,super.print() 会调用父类的原型方法。类似于把父类的属性直接搬到这里。

if(new.target === Animal)
{
       throw new Error("不能实例化抽象类");
}

当我们不想让一个抽象类可以创建对象时,可以加一个 new.target 的判断。因为如果这个类是抽象的,就不应该被实例化,这样会违反逻辑。
this 的指向不会在定义中更改,只会根据调用的对象决定。