在面向对象编程中,继承是一个非常重要的概念。在 JavaScript 中,通过原型链实现继承机制。从 ES6 开始,引入了 class 关键字来更方便地创建类,并且引入了 super 关键字来调用父类的构造函数和方法。
类与继承的基本概念
在 JavaScript 中,类是基于原型的继承机制的一种语法糖。使用 class 关键字可以定义一个类,而类之间的继承则通过 extends 关键字来实现。
// www.javascriptcn.com code example
// 定义一个父类
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
// 定义一个子类
class Dog extends Animal {
// ...
}在这个例子中,Dog 类通过 extends 关键字继承了 Animal 类。
使用 super 调用父类构造函数
当一个子类继承自一个父类时,子类的构造函数中需要调用父类的构造函数来初始化继承自父类的属性。这时就需要使用 super 关键字。需要注意的是,super() 必须在子类构造函数中的 this 关键字之前被调用。
// www.javascriptcn.com code example
class Dog extends Animal {
constructor(name, breed) {
super(name); // 调用父类的构造函数
this.breed = breed;
}
speak() {
console.log(`${this.name} barks.`);
}
}
const myDog = new Dog('Rex', 'German Shepherd');
console.log(myDog.name); // 输出: Rex
console.log(myDog.breed); // 输出: German Shepherd
myDog.speak(); // 输出: Rex barks.在这个例子中,super(name) 调用了父类 Animal 的构造函数,从而初始化了 name 属性。然后,Dog 类的构造函数继续初始化自己的属性 breed。
调用父类的方法
除了构造函数之外,super 还可以用来调用父类的其他方法。这在子类需要扩展或修改父类行为的情况下特别有用。
// www.javascriptcn.com code example
class Cat extends Animal {
constructor(name, color) {
super(name);
this.color = color;
}
speak() {
super.speak(); // 调用父类的 speak 方法
console.log(`${this.name} purrs.`);
}
}
const myCat = new Cat('Whiskers', 'gray');
myCat.speak(); // 输出: Whiskers makes a noise. Whiskers purrs.在这个例子中,super.speak() 被用来调用父类 Animal 的 speak 方法。然后子类 Cat 继续执行自己的逻辑,输出 purrs。
使用 super 调用父类静态方法
除了实例方法之外,super 还可以用来调用父类的静态方法。静态方法可以通过类名直接调用,而不是通过实例。
// www.javascriptcn.com code example
class Bird extends Animal {
constructor(name, canFly) {
super(name);
this.canFly = canFly;
}
static isFlying(bird) {
return bird.canFly ? `${bird.name} is flying.` : `${bird.name} cannot fly.`;
}
}
class Parrot extends Bird {
constructor(name, canFly) {
super(name, canFly);
}
static isFlying(parrot) {
return super.isFlying(parrot) + ` ${parrot.name} is very good at flying.`;
}
}
const myParrot = new Parrot('Polly', true);
console.log(Parrot.isFlying(myParrot)); // 输出: Polly is flying. Polly is very good at flying.在这个例子中,super.isFlying(parrot) 调用了父类 Bird 的静态方法 isFlying。然后子类 Parrot 继续执行自己的逻辑,输出额外的信息。
总结
通过 super 关键字,JavaScript 提供了一种简洁而强大的方式来处理继承中的构造函数调用和方法调用。这使得子类能够轻松地扩展或修改父类的行为,同时保持代码的清晰和可维护性。