14

I need to dynamically define classes so have written a code generator in my ES6 code:

function makeClass(className, baseClass = _DefaultBaseClass, ...args) {
  return (
    eval(`
      class ${className} extends ${baseClass} {
        constructor(${...args}) {
          super(${...args})
        }
      }
   `)
  )
}

'_DefaultBaseClass' is an empty class used to simplify the above generator function logic:

class _DefaultBaseClass() {
  constructor() {}
}

Everything works fine with the generator code, except for the spread operator. The spread operator itself works fine in my project outside of the template literal in this example.

I'm using the following webpack Babel presets/plugins: 'react', 'es2015', 'stage-2', 'transform-runtime'.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Ethan
  • 9,558
  • 5
  • 27
  • 24
  • Why not simply drop the `constructor` altogether when it's only calling `super` - the default constructor does just that anyway – Bergi Mar 07 '17 at 03:36
  • 3
    [**`...` is not an operator**](http://stackoverflow.com/questions/37151966/what-is-spreadelement-in-ecmascript-documentation-is-it-the-same-as-spread-oper/37152508#37152508). It is part of the syntax of array literals, function definitions, function calls and array destructuring assignment. It's not a standalone thing. `...` is not part of template literals. – Felix Kling Mar 07 '17 at 05:59
  • @FelixKling Thanks for the info; very helpful. – Ethan Mar 07 '17 at 09:25
  • 2
    @FelixKling but you can do ``: `${[...args]}` `` and works! :) – robe007 Mar 14 '19 at 18:11

1 Answers1

13

As mentioned in the comments ... is bound to specific use cases. ${...args} wouldn't even make much sense. What should be the result? E.g. if ${...args} would be equivalent to ${args[0],args[1]}, then it would evaluate to the value of args[1], because here , is a comma operator.

Template literals can contain arbitrary expressions, so you can do the following:

`${args.join(",")}`
a better oliver
  • 26,330
  • 2
  • 58
  • 66
  • Thanks for the answer / insight. The thinking behind my inclination to use `${...args}` was that in the `makeClass` function body, `args` is an array; therefore I thought I ought to be able to 'spread' the array in the eval section using the `...` syntax to achieve multiple inputs to the constructor. Your point about the comma operator is very helpful. – Ethan Mar 07 '17 at 09:22