Matías Fidemraizer Matías Fidemraizer - 9 days ago 5
Javascript Question

Call base class constructor without manuallys supplying arguments

Imagine that we've the following

class
:

class A {
constructor(x, y, z) {
}
}

class B extends A {
constructor(x, y, z) {
super(x, y, z);
}
}


What if we want to call
super(...)
with
arguments
or rest arguments:

super.apply(this, arguments);
super.apply(this, args);


This won't work:
super.*
is not allowed before
super()
.

Is there any alternative to avoid manually supplying arguments?

Answer

Use spread notation:

super(...args);

E.g.:

class B extends A {
    constructor(...args) {
        super(...args);
    }
}

(super(...arguments) would also work.)

But it's worth noting that for the A and B shown, you don't need to provide a constructor for B at all. The default constructor┬╣ for a derived class is exactly as shown above, so:

class B extends A {
}

would do exactly the same thing.

Further examples below.

In a comment, you said there are 10 (!) parameters to the base class and you only need two of them in your subclass, and my impression is you meant the first two. If so:

class B extends A {
    constructor(first, second, ...rest) {
        super(first, second, ...rest);
        // Use `first` and `second` here...
    }
}

If you meant two in the middle, we can do that with destructuring as well:

class B extends A {
    constructor(...args) {
        super(...args);
        let {1: second, 2: third} = args;
        // Use `second` and `third` here...
    }
}

More Examples:

class A {
  constructor(x, y, z) {
    console.log(`A: ${x}, ${y}, ${z}`);
  }
}

// No constructor defined; gets default
class B1 extends A {}

// Explicit version of the default constructor
class B2 extends A {
  constructor(...args) {
    super(...args);
  }
}

// Using `arguments` instead:
class B3 extends A {
  constructor() {
    super(...arguments);
  }
}

// If the subclass accepts different args
class B4 extends A {
  constructor(q, ...rest) {
    super(...rest);
    console.log(`B4: q = ${q}`);
  }
}

class B5 extends A {
  constructor(...args) {
    super(...args);
    // They don't have to be called `y` and `z`, I'm just being consistent
    let { 1: y, 2: z } = args;
    console.log(`B5: y = ${y}, z = ${z}`);
  }
}

new B1(1, 2, 3);
new B2(4, 5, 6);
new B3(7, 8, 9);
new B4('q', 'x', 'y', 'z');
new B5('first', 'second', 'third');


┬╣ "the default constructor for a subclass is exactly as shown above" Note how this is different from languages like Java or C#, where the default constructor would accept no args and call super()/base() with no args.