Class 继承 - 添加参数而不重写父构造函数参数

Class inheritance - add argument without rewriting parent constructor arguments

我想扩展以下内容class:

class Person {
    constructor(name, age) {
        this._name = name;
        this._age = age;
    }
  
    get name() {
        return this._name;
    }
  
    get age() {
        return this._age;
    }
}

...通过添加 sport 及其 getter:

class Athlete extends Person {
    constructor(name, age, sport) {
        super();
        this._name = name;
        this._age = age;
        this._sport = sport;
    }
  
    get sport() {
        return this._sport;
    }
}

虽然上述方法有效,但我想避免重复基父构造函数的参数。以下方法行不通:

class Athlete extends Person {
    constructor(sport) {
        super();
        this._sport = sport;
    }
  
    get sport() {
        return this._sport;
    }
}

let athlete = new Athlete('Peter', 29, 'cricket');
console.log(athlete.name, athlete.age, athlete.sport); // name and age are not inherited, is returned 'undefined'

那么,如何在不重写基础 Class 的情况下向子 Class 添加字段?

您需要传递参数,但您可以通过将它们传递给 super():

来避免分配所有参数
class Athlete extends Person {
    constructor(name, age, sport) {
        super(name, age); // pass arguments to super()
        this._sport = sport;
    }
  
    get sport() {
        return this._sport;
    }
}

let athlete = new Athlete('Peter', 29, 'cricket');
console.log(athlete.name, athlete.age, athlete.sport);

你想要的可以实现(使用destructured parameters...args)语法来表示任意数量的参数),但是,不建议这样做(至少我是这样做的) ,它有一定的代价,其中一些是可读性、易于调试、不易出错的代码等传递错误数量的参数):

class Person {
    constructor(name, age) {
        this._name = name;
        this._age = age;
    }
  
    get name() {
        return this._name;
    }
  
    get age() {
        return this._age;
    }
}

class Athlete extends Person {
    constructor(...args) {
        let sport = args.splice(-1)[0];
        super(...args);
        this._sport = sport;
    }
    
    get sport() {
        return this._sport;
    }
}

let athlete = new Athlete('Peter', 29, 'cricket');
console.log(athlete.name, athlete.age, athlete.sport);

同样可以使用arguments对象来实现:

class Person {
    constructor(name, age) {
        this._name = name;
        this._age = age;
    }
  
    get name() {
        return this._name;
    }
  
    get age() {
        return this._age;
    }
}

class Athlete extends Person {
    constructor() {
        let args = Array.from(arguments);
        let sport = args.splice(-1)[0];
        super(...args);
        this._sport = sport;
    }
    
    get sport() {
        return this._sport;
    }
}

let athlete = new Athlete('Peter', 29, 'cricket');
console.log(athlete.name, athlete.age, athlete.sport);