ZetCode

JavaScript super 关键字

最后修改于 2025 年 4 月 16 日

在本文中,我们将展示如何使用 JavaScript 中的 super 关键字访问父类成员。

super 关键字

super 关键字用于访问和调用对象父类上的函数。它可以通过两种方式使用:作为构造函数中的函数调用,或者作为属性查找以访问父类方法。

在构造函数中,在使用 this 之前必须调用 super()。这确保了父类已正确初始化。在方法中,super 提供了对父类实现的访问权限。

super 关键字对于在 JavaScript 类中实现继承和方法重写至关重要。它维护了父类和子类之间的原型链。

构造函数中的基本 super

以下示例演示了在构造函数中 super 的基本用法。

main.js
class Animal {
    constructor(name) {
        this.name = name;
    }
}

class Dog extends Animal {
    constructor(name, breed) {
        super(name);
        this.breed = breed;
    }
}

const myDog = new Dog('Max', 'Labrador');
console.log(myDog);

这里,super(name) 使用 name 参数调用父类构造函数。Dog 类继承 Animal 并添加一个 breed 属性。 super 调用必须在访问构造函数中的 this 之前进行。

$ node main.js
Dog { name: 'Max', breed: 'Labrador' }

调用父类方法

可以使用 super 关键字调用父类方法。

main.js
class Vehicle {
    startEngine() {
        return 'Engine started';
    }
}

class Car extends Vehicle {
    startEngine() {
        return `${super.startEngine()} - Car ready to drive`;
    }
}

const myCar = new Car();
console.log(myCar.startEngine());

此示例展示了如何扩展父类方法。 Car 类重写 startEngine 但仍然使用 super 调用父类的实现。这允许方法扩充而不是完全替换。

$ node main.js
Engine started - Car ready to drive

访问父类的静态方法

super 也可以访问父类的静态方法。

main.js
class MathOperations {
    static add(a, b) {
        return a + b;
    }
}

class AdvancedMath extends MathOperations {
    static add(a, b, c) {
        return super.add(a, b) + c;
    }
}

console.log(AdvancedMath.add(1, 2, 3));

这里我们使用 super 调用父类的静态方法。AdvancedMath 类扩展了 add 功能,同时重用了父类的实现。 静态方法在类本身上调用,而不是在实例上调用。

$ node main.js
6

对象字面量中的 Super

super 关键字可以在带有 __proto__ 属性的对象字面量中使用。

main.js
const parent = {
    greet() {
        return 'Hello from parent';
    }
};

const child = {
    __proto__: parent,
    greet() {
        return `${super.greet()} and child`;
    }
};

console.log(child.greet());

此示例演示了在带有原型链的对象字面量中使用 super。子对象继承自父对象并重写 greet 方法。 Super 在重写的方法中提供了对父类实现的访问权限。

$ node main.js
Hello from parent and child

带有 getter 和 setter 的 Super

super 关键字与类中的 getter 和 setter 一起使用。

main.js
class Person {
    constructor(name) {
        this._name = name;
    }
    
    get name() {
        return this._name;
    }
}

class Employee extends Person {
    get name() {
        return `${super.name} (employee)`;
    }
}

const emp = new Employee('John');
console.log(emp.name);

在这里,我们重写了一个 getter 方法并使用 super 访问父类的实现。 Employee 类扩展了 name getter 以添加附加信息,同时保留了原始功能。

$ node main.js
John (employee)

多重继承级别

super 适用于多个继承级别。

main.js
class A {
    method() {
        return 'A';
    }
}

class B extends A {
    method() {
        return `${super.method()} B`;
    }
}

class C extends B {
    method() {
        return `${super.method()} C`;
    }
}

const instance = new C();
console.log(instance.method());

此示例展示了 super 遍历多个继承级别。每个类都扩展了前一个类并基于其方法实现进行构建。调用链遵循原型层次结构向上。

$ node main.js
A B C

实际用例:扩展内置类

这是一个使用 super 扩展内置类的实用示例。

main.js
class CustomArray extends Array {
    sum() {
        return this.reduce((acc, val) => acc + val, 0);
    }
    
    first() {
        return super[0];
    }
}

const nums = new CustomArray(1, 2, 3, 4);
console.log(nums.sum());
console.log(nums.first());

此代码扩展了内置的 Array 类以添加自定义方法。 sum 方法是新功能,而 first 使用 super 访问数组索引。这演示了如何在现有类的基础上构建,同时保留它们的功能。

$ node main.js
10
1

来源

super - 语言参考

在本文中,我们演示了如何使用 super 关键字访问 JavaScript 中的父类成员。

作者

我的名字是 Jan Bodnar,我是一位充满热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。迄今为止,我撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

查看 所有 JavaScript 教程。