基于原型的继承:
在 JavaScript 中,所有的对象都有一个隐藏的 __proto__ 属性,指向它的构造函数的原型对象(prototype)。该原型对象也有一个自己的原型对象(proto),层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。
我们可以使用 obj.__proto__ 访问对象的原型;如果我们想要读取 obj 的一个属性或者调用一个方法,并且它不存在,那么 JavaScript 就会尝试在原型中查找它。
代码示例:
let animal = {
eats: true
};
let rabbit = {
jumps: true
};
rabbit.__proto__ = animal; // 设置 rabbit的原型为animal
alert( rabbit.eats ); // true
//当alert试图读取rabbit.eats时,因为它不存在于rabbit中
//JavaScript 会顺着Prototype引用,在animal中查找
alert( rabbit.jumps ); // true
基于类的继承:
类继承是一个类扩展另一个类的方式,类通过extend关键字实现继承。
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed = speed;
alert(`${this.name} runs with speed ${this.speed}.`);
}
stop() {
this.speed = 0;
alert(`${this.name} stands still.`);
}
}
let animal = new Animal("My animal");
class Rabbit extends Animal {
hide() {
alert(`${this.name} hides!`);
}
}
let rabbit = new Rabbit("White Rabbit");
rabbit.run(5); // White Rabbit runs with speed 5. rabbit.hide(); // White Rabbit hides!
class Rabbit 继承自 class Animal,Class Rabbit 的对象可以访问例如 rabbit.hide() 等 Rabbit 的方法,还可以访问例如 rabbit.run() 等 Animal 的方法。
当重写一个constructor时:
- 在使用
this之前,我们必须在Child的 constructor 中将父 constructor 调用为super()。
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
}
class Rabbit extends Animal {
constructor(name, earLength) {
super(name);
//如果不按照这么写,而是
//this.speed = 0
//this.name = name
//会报错,派生的 constructor 必须调用 super才能执行其父类的 constructor,否则 `this` 指向的那个对象将不会被创建
this.earLength = earLength;
}
}
let rabbit = new Rabbit("White Rabbit", 10);
alert(rabbit.name); // White Rabbit
alert(rabbit.earLength); // 10