Automatically set arguments as instance properties in ES6

Felix Kling’s comment outlines the closest you’ll get to a tidy solution for this. It uses two ES6 features—Object.assign and the object literal property value shorthand.

Here’s an example with tree and pot as the instance properties:

class ChristmasTree {
    constructor(tree, pot, tinsel, topper) {
        Object.assign(this, { tree, pot });
        this.decorate(tinsel, topper);
    }

    decorate(tinsel, topper) {
        // Make it fabulous!
    }
}

Of course, this isn’t really what you wanted; you still need to repeat the argument names, for one thing. I had a go at writing a helper method which might be a bit closer…

Object.autoAssign = function(fn, args) {

    // Match language expressions.
    const COMMENT  = /\/\/.*$|\/\*[\s\S]*?\*\//mg;
    const ARGUMENT = /([^\s,]+)/g;

    // Extract constructor arguments.
    const dfn     = fn.constructor.toString().replace(COMMENT, '');
    const argList = dfn.slice(dfn.indexOf('(') + 1, dfn.indexOf(')'));
    const names   = argList.match(ARGUMENT) || [];

    const toAssign = names.reduce((assigned, name, i) => {
        let val = args[i];

        // Rest arguments.
        if (name.indexOf('...') === 0) {
            name = name.slice(3);
            val  = Array.from(args).slice(i);
        }

        if (name.indexOf('_') === 0) { assigned[name.slice(1)] = val; }

        return assigned;
    }, {});

    if (Object.keys(toAssign).length > 0) { Object.assign(fn, toAssign); }
};

This auto-assigns any parameters whose names are prefixed with an underscore to instance properties:

constructor(_tree, _pot, tinsel, topper) {
    // Equivalent to: Object.assign({ tree: _tree, pot: _pot });
    Object.autoAssign(this, arguments);
    // ...
}

It supports rest parameters, but I omitted support for default parameters. Their versatility, coupled with JS’ anaemic regular expressions, makes it hard to support more than a small subset of them.

Personally, I wouldn’t do this. If there were a native way to reflect on the formal arguments of a function, this would be really easy. As it is, it’s a mess, and doesn’t strike me as a significant improvement over Object.assign.

Leave a Comment