面试题答案
一键面试在JavaScript的子类构造函数中super
的作用
- 调用父类构造函数:
- 在子类构造函数中,
super
用于调用父类的构造函数,以便初始化继承自父类的属性。因为在JavaScript中,子类的构造函数默认不会自动调用父类的构造函数。 - 示例:
class Animal { constructor(name) { this.name = name; } } class Dog extends Animal { constructor(name, breed) { super(name); // 调用父类Animal的构造函数,初始化name属性 this.breed = breed; } } const myDog = new Dog('Buddy', 'Golden Retriever'); console.log(myDog.name); // 输出: Buddy console.log(myDog.breed); // 输出: Golden Retriever
- 在子类构造函数中,
- 在访问
this
之前必须调用super
:- 如果在子类构造函数中不先调用
super
就访问this
,会抛出一个错误。这是因为在调用super
之前,this
并未被正确初始化。JavaScript引擎需要通过super
调用父类构造函数来正确设置this
的原型链和初始状态。 - 示例:
class Animal { constructor(name) { this.name = name; } } class Dog extends Animal { constructor(name, breed) { // 下面这行会报错,因为在访问this之前没有调用super console.log(this); super(name); this.breed = breed; } }
- 运行上述代码会抛出类似于“ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor”的错误。
- 如果在子类构造函数中不先调用
在JavaScript的子类普通方法中super
的作用
- 调用父类方法:
- 在子类的普通方法中,
super
可用于调用父类的同名方法,实现对父类方法的扩展或重写。 - 示例:
class Animal { speak() { return 'I am an animal'; } } class Dog extends Animal { speak() { const parentSpeak = super.speak(); // 调用父类的speak方法 return `${parentSpeak} and I am a dog`; } } const myDog = new Dog(); console.log(myDog.speak()); // 输出: I am an animal and I am a dog
- 在子类的普通方法中,
- 访问父类属性:
- 通过
super
,子类方法可以访问父类的属性(如果父类属性不是私有的)。不过在ES6类中,通常更常见的是调用父类方法来间接访问属性。 - 示例:
class Animal { constructor(name) { this.name = name; } getName() { return this.name; } } class Dog extends Animal { constructor(name, breed) { super(name); this.breed = breed; } describe() { const animalName = super.getName(); // 通过调用父类方法访问父类属性 return `${animalName} is a ${this.breed}`; } } const myDog = new Dog('Buddy', 'Golden Retriever'); console.log(myDog.describe()); // 输出: Buddy is a Golden Retriever
- 通过
- 实现多态性:
- 多态性在JavaScript中通过子类重写父类方法并使用
super
来实现。不同的子类可以根据自身需求对父类方法进行不同的实现。 - 示例:
class Shape { calculateArea() { return 0; } } class Rectangle extends Shape { constructor(width, height) { super(); this.width = width; this.height = height; } calculateArea() { return this.width * this.height; } } class Circle extends Shape { constructor(radius) { super(); this.radius = radius; } calculateArea() { return Math.PI * this.radius * this.radius; } } const rectangle = new Rectangle(5, 10); const circle = new Circle(5); console.log(rectangle.calculateArea()); // 输出: 50 console.log(circle.calculateArea()); // 输出: 约78.54
- 在这个例子中,
Rectangle
和Circle
子类都重写了Shape
父类的calculateArea
方法,展示了多态性。super
在子类构造函数中用于初始化继承自父类的部分,而在重写的方法中可以选择是否调用父类的同名方法来进行扩展。
- 多态性在JavaScript中通过子类重写父类方法并使用