Skip to content Skip to sidebar Skip to footer

Generic Reading Of Arguments From Multiple Constructor Calls

Follow-up question to Read arguments from constructor call: The accepted solution allows me to get arguments passed into a constructor by defining a wrapper class that captures and

Solution 1:

Yes, you can create generic wrapper which will add args property to instance of any passed constructor:

classPlugin {
  constructor (arg1, arg2) {
    this.arg1 = arg1
    this.arg2 = arg2    
  }
}

functionwrapper(initial) {
  // Rewrite initial constructor with our functionreturnfunctiondecoratedContructor(...args) {
    // Create instance of initial objectconst decorated = newinitial(...args)

    // Add some additional properties, methods
    decorated.args = [...args]

    // Return instantiated and modified objectreturn decorated
  }
}

const decoratedPlugin = wrapper(Plugin)
const plugin = newdecoratedPlugin('argument', { 'argument2': 1 })
console.log(plugin.args)

FYI: it's not safe to add properties without some prefix. Consider adding __ or something like this to your property, because you can accidentally rewrite some inner object property.

Solution 2:

I was able to get this working with a modification to @guest271314's suggestion, namely, you need to pass ...initArgs to super(), otherwise webpack will fail with a TypeError: Cannot read property '...' of undefined.

Also took @terales's point into account about making sure to prefix my additional properties.

const exposeConstructorArgs = (Plugin, ...args) => {
  const ExposedPlugin = classextendsPlugin{
    constructor(...initArgs) {
      super(...initArgs);

      this.__initArgs__ = initArgs;
    }

    get __initArgs() {
      returnthis.__initArgs__;
    }
  };

  return Reflect.construct(ExposedPlugin, args);
};

// ...const dllPlugin = exposeConstructorArgs(webpack.DllPlugin, {
  name: '[name]',
  path: path.join(buildDir, '[name].json'),
});

// ...const pluginConfig = dllPlugin.__initArgs[0];

expect(pluginConfig.name).toEqual('[name]');

Solution 3:

You can use a generic function where class expression is used within function body. Pass reference to the class or constructor and parameters expected to be arguments within the instance to the function call.

functionPlugin() {}

functionPlugin2() {}

functionPluginWrapper(pluginRef, ...args) {
  letMyPlugin = classextends pluginRef {
    constructor() {
      super();
      this.args = [...arguments];
    }
    getArgs() {
      returnthis.args;
    }
  }
  returnReflect.construct(MyPlugin, args);
};

const anInstance = PluginWrapper(Plugin, {
  a: 'path'
});

console.log(anInstance.getArgs(), anInstance instanceofPlugin);

const aSecondInstance = PluginWrapper(Plugin2, "arg1", "arg2", {
  b: 'anotherPath'
});

console.log(aSecondInstance.getArgs(), aSecondInstance instanceofPlugin2);

Post a Comment for "Generic Reading Of Arguments From Multiple Constructor Calls"