Reputation: 8041
Look at the below example:
class Parent {
constructor({ parentOnlyArg = 'default value' } = {}) {
this.parentOnlyArg = parentOnlyArg;
}
}
class Child extends Parent {
// this class and also any class inheriting from it
constructor({ visibleStyle = 'inline' } = {}) {
// I want to pass argument to super as an object
super(/** args **/);
this.visibleStyle = visibleStyle;
}
}
class Child2 extends Parent {
// Specifying parentOnlyArg as default will change the behaviour
constructor({ parentOnlyArg = 'another parent value',
someOther = 'value' } = {}) {
// I want to pass argument to super as an object
super(/** args **/);
this.someOther = someOther;
}
}
Is it possible to pass on the constructor argument to super?
Seems like it was simpler than I thought
super(...arguments);
I can then create Child
using
var c1 = new Child(); // c.parentOnlyArg = 'default value'
var c2 = new Child2(); // c.parentOnlyArg = 'another parent value'
var c3 = new Child({ parentOnlyArg: 'changed again' }); // c.parentOnlyArg = 'changed again'
Upvotes: 0
Views: 6283
Reputation: 29906
You could use object destructuring with rest properties. It is not yet implemented by browsers, but BabelJs can transpile it.
function assertEmpty(obj) {
if (Object.keys(obj).length > 0) {
throw new Error("Unexpected parameters");
}
}
class A {
constructor({ a = "foo", ...rest } = {}) {
assertEmpty(rest);
console.log("new A " + a);
}
}
class B extends A {
constructor({ b = "bar", ...rest } = {}) {
super(rest);
console.log("new B " + b);
}
}
new B({a:2}); // prints 'new A 2', 'new B bar'
new B({a:4, b:5, c:6}); // throws 'Unexpected parameters'
In the above snippet parent classes don't see the params consumed by the descendants. If you have problems with that you can do it either as @Bergi or @loganfsmyth suggested. For example:
class A {
constructor(params = {}) {
const { a = "foo" } = params;
console.log("a=" + a);
}
}
class B extends A {
constructor(params = {}) {
const { b = "bar" } = params;
super(params);
console.log("b=" + b);
}
}
new B({a:2}); // prints a=2 b=bar
new B({b:5}); // prints a=foo b=5
Upvotes: 2
Reputation: 463
A quick-win is to use the arguments
object. It is an array containing all parameters passed to a function.
More information on the MDN.
In practice, you can access to the first parameter of your function thanks to arguments[0]
.
class Child extends Parent {
constructor({ parentOnlyArg = 'value',
visibleStyle = 'inline' } = {}) {
super(arguments[0]);
[...]
}
}
Upvotes: 1