1

Relative newbie to JS and node(though I don't think the fact that it's node matters, but just in case), but learning fast. Probably more detail in this question than needed to ask it, but I'm attempting to include in here some explanation of what I do and don't already understand, in case that's helpful context. I suspect there's something simple I'm missing here...

I have a class A with a bunch of (static, though I don't think that matters?) functions in it. They all do pretty specific things. I have another class B calling functions in A based on the desired function name and arguments being in variables in B.

I understand I could do something like this:

class A {
    static doIt(theFunctionName, theArguments) {
        if (theFunctionName == 'asdf') {
            this.asdf(theArguments);
        } else if (theFunctionName == 'qwer') {
            this.qwer(theArguments);
        } else if (theFunctionName == 'zxcv') {
            this.zxcv(theArguments);
        // } else if ( .. etc ...) {
        //  ... etc ...
        } else {
            //return some kind of error or whatever
        }
    }

    static asdf(theArguments) {
        //do stuff and return something
    }
    static qwer(theArguments) {
        //do stuff and return something
    }
    static zxcv(theArguments) {
        //do stuff and return something
    }
}


class B {
    constructor(...) {
        this.theFunctionName = ...;
        this.theArguments = [...];
    }
    myResult = A.doIt(this.theFunctionName, this.theArguments);
}

Further, I understand I can access properties of an object dynamically:

obj[myKey] = something;

or

myResult = obj[key]

But functions?

I believe I'm looking for some way to do the latter with functions not just properties - some way to do the functions stuff more dynamically without all the if ... else if ... ?

I understand functions are first class in JS, and can be passed around like objects. But I'm not sure that helps here since I'm not passing the functions themselves, I'm choosing a function to call based on its name and arguments in variables... right?

I've tried a couple of things attempting to use the principles from the properties examples with functions but not getting the desired results. I'm guessing either this really can't be done (without all the if... else if... ... or I'm missing something simple.

Any help greatly appreciated. Thanks!

1 Answer 1

1

Functions are first-class members in JavaScript. An object that has a property whose value is a string is not fundamentally that different from one with a property whose value is a function. Ordinary bracket notation works just fine with function properties and methods:

class A {
    static doIt(theFunctionName, theArguments) {
        const fn = this[theFunctionName];
        if (fn) {
          return fn(theArguments);
        } else {
            //return some kind of error or whatever
        }
    }

    static asdf(theArguments) {
        //do stuff and return something
    }
    static qwer(theArguments) {
        //do stuff and return something
        return 'quer ran';
    }
    static zxcv(theArguments) {
        //do stuff and return something
    }
}


class B {
    constructor() {
        this.theFunctionName = 'qwer';
        this.theArguments = 'foobar';
        console.log(A.doIt(this.theFunctionName, this.theArguments));
    }   
}
const b = new B();

That said, this design pattern looks a bit odd - A does not have any own-properties on instances, so it's somewhat weird for A to be a class; it'd make more sense to be a normal object.

const A = {
    doIt(theFunctionName, theArguments) {
        const fn = this[theFunctionName];
        if (fn) {
          return fn(theArguments);
        } else {
            //return some kind of error or whatever
        }
    },
    asdf(theArguments) {
        //do stuff and return something
    },
    qwer(theArguments) {
        //do stuff and return something
        return 'quer ran';
    },
    zxcv(theArguments) {
        //do stuff and return something
    }
}


class B {
    constructor() {
        this.theFunctionName = 'qwer';
        this.theArguments = 'foobar';
        console.log(A.doIt(this.theFunctionName, this.theArguments));
    }   
}
const b = new B();

Sign up to request clarification or add additional context in comments.

3 Comments

1. Thanks. That makes sense & would appear to be the 'simple' thing I was 'missing' :-) 2. Thanks for the tip about class vs object. Admittedly I'm coming from languages with traditional class based OOP and still getting my head around JS's prototype thing. Good tip for elsewhere in my app, though in this case there's more to it that I didn't include. But… I'll reconsider that given your point. That said, isn't 'class' just syntax sugar for certain object syntax anyway? Underneath is there any significant difference between your class code & your const code?
isn't 'class' just syntax sugar for certain object syntax anyway? No, a class is very different. With a class, the methods are being put onto the ClassName.prototype object. Classes can be instantiated with new (and readers of the code will expect a class to be instantiated for some purpose, else there's no point to the class). Classes also have various additional syntax, such as class fields, constructors, super, and static. But if all you want is to organize functions into a data structure, using a plain object is much simpler and will make more sense to readers of the code.
@CaptainPerformance Fair enough. Makes sense. I appreciate the explanation. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.