Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript Passing variable arguments to superclass constructor

Tags:

javascript

What is the best/recommended way to pass variable arguments to a superclass constructor? The background explains the problem I'm trying to solve.

Background

I'm porting some code from Java to Javascript. One of the coding patterns that Java has is function overloading. Java picks the best match to determine what function to call. This becomes interesting when the function is a Class constructor method.

So code in Java might be

public class MyParser extends Parser {
    public int parse(String str) { super(str); ... } 
    public int parse(String str, int base) { super(str, base); ... }
}

In Javascript becomes:

class MyParser extends Parser {
    constructor(){
        super(arguments); // THIS DOES NOT WORK
        if (arguments.length === 1 && typeof arguments[0] === 'string'){
            constructor_1arg(arguments[0]);
        } else if (...){
            constructor_2args(arguments[0], arguments[1]);
        }
    }
}

So I was wondering what is the best way to handle this case?

Possible solution

NOTE: I'm asking this because calling super() is a special case in a constructor and you can only call it once. So I didn't expect this to work but it did (in NodeJS v8.2).

class MyParserTry2 extends Parser {
    constructor(){
        console.log('MyParser2 passed ' + arguments.length + ' args. ', arguments);
        if (arguments.length === 1 && typeof arguments[0] === 'string'){
            super(arguments[0]);
            this.constructor_1arg(arguments[0]);
        } else if (arguments.length === 2 && typeof arguments[0] === 'string'){
            super(arguments[0], arguments[1]);
            this.constructor_2args(arguments[0], arguments[1]);
        }
    }

    constructor_1arg(arg1){ }
    constructor_2args(arg1, arg2){ }
}

I thought super() had to be called before other code, but this might be from another language. Does Javascript standard support calling super() as shown in this code snippet?

Previous answers/research

I searched StackOverflow for answers and found several similar questions but not this one. I found these questions or postings:

  • Passing all arguments forward to another javascript function. Thanks to @BobStein-VisiBone who suggested that this question be re-opened because it is slightly different than the following question. He also suggested searching on javascript pass all callers arguments to inner function
  • Passing an array as a function parameter
  • It was important to realize that arguments is not an array and can't be used to just pass along arguments to an inner function. See Understanding what arguments object really is
  • Using apply() was suggested in some posts, but I didn't see anyone using super.apply(this, arguments). If this is the best way to handle this question suggest this as the answer, but realize that my observations are that "this" is not set until after super() is called. Interesting...
  • What I tried is at JSFiddle. You'll have to open your browsers console to see log messages. Sorry it's not easier to use.

None of the above, however, answer my question.

So... What is the best/recommended way to pass variable arguments to a superclass constructor?

like image 335
PatS Avatar asked Dec 05 '17 17:12

PatS


People also ask

How do you forward an argument to a super class constructor?

In AS2, you can pass parameters to a super class's constructor using super() . This is handy, but what if your constructor accepts an undefined number of parameters, and you want to pass them all to your super constructor (think of the Array class, for instance)?

What does super () do in JavaScript?

The super keyword in JavaScript acts as a reference variable to the parent class. It is mainly used when we want to access a variable, method, or constructor in the base class from the derived class.

What does Super do in JavaScript constructor?

The super keyword is used to access properties on an object literal or class's [[Prototype]], or invoke a superclass's constructor.

Do you have to call super in constructor JavaScript?

Neither the base (parent) nor derived (child) class requires a constructor, nor does the child class require a super() call. If you omit either constructor, an assumed one is present. However, if you do declare a constructor in a derived class, you'll need to call super() in it.


1 Answers

class SomeClass extends SomeSuperClass {
 constructor(...args){ super(...args); }
}

Using arguments is deprecated so you could rather use rest/spread operators.

like image 136
Jonas Wilms Avatar answered Oct 08 '22 22:10

Jonas Wilms