1

I already have a function for modifing other class methods:

class MyClass {
    constructor() {
        this.num = 1;
    }
    inc(){
        this.num++;
    }
}

runAfterMethod(classHandle, methodName, executeAfter) {
    const oldHandle = classHandle.prototype[methodName];
    classHandle.prototype[methodName] = function () {
        const returnValue = oldHandle.apply(this, arguments);
        //@ts-ignore
        executeAfter.apply(this, arguments);
        return returnValue;
    };
}

runAfterMethod(MyClass, "inc", function() {console.log(this.num)})
new MyClass().inc(); // Prints 2

However, this does not work for the constructor of the class (because it is technically the class itself)

What I would really be happy with is something that mimics this behavior:

class MyClass {
    constructor() {
        this.num = 1;
    }
}

extendConstructor(MyClass, function(){
    this.str = "hello world"
})

new MyClass(); // num: 1, str: "hello world"

I have looked at things like How to modify the constructor of an ES6 class however, they all require = somewhere, which does not work inside of a function (where that only changes the value of the class inside the function, not the class itself)

7
  • 3
    I think that you want to implement what is called "decorator pattern", not to be confused with decorators. In a nutshell: you don't modify the constructor; you create an instance of the class and then give it as argument to the constructor of another class which is quite similar to the original class, but with all the changes you want to make Commented Jan 24, 2022 at 1:21
  • You may want to look into tools like stampit, they have some neat ways of managing object creation. I haven't used recent versions, but older ones were very helpful in creating composed OO code without relying on class syntax. Commented Jan 24, 2022 at 1:31
  • I found this free resource on decorator pattern in case you are interested. Commented Jan 24, 2022 at 1:38
  • Indeed there is no to do this without an assignment. Just write MyClass = extendConstructor(MyClass, …);. Nothing wrong with that. Commented Jan 24, 2022 at 1:44
  • See here and there for how that could be achieved. Commented Jan 24, 2022 at 1:52

1 Answer 1

1

Mutating the existing class is really weird. What would be much less of a code smell IMO would be to create a wrapper around the class that instantiates the class, then calls it with your custom callback, and then returns the instance - it'd be a lot more straightforward. Would that work for your purposes?

class MyClass {
    constructor() {
        this.num = 1;
    }
}

const extendConstructor = (theClass, callback) => function(...args) {
  const instance = new theClass(...args);
  callback.call(instance);
  return instance;
};
const Extended = extendConstructor(MyClass, function(){
    this.str = "hello world"
})

console.log(new Extended()); // num: 1, str: "hello world"

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

1 Comment

Unfortunately, it would not, as it is being used for a mod-loader in which mods may change things about components that the game uses internally (such as letting buildings be rotated or mirrored by adding to a position component. However in another case yes this would work

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.