4
\$\begingroup\$

I'm delving into JavaScript, and ES6, but want to be able to pass additional options to functions after a spread object. Coming from Python, you'd just use keyword arguments, such as def sum(*args, fn=add), where in JavaScript you'd either need the optional argument before the required arguments, or to handle it in the function. I decided that it'd be simpler to wrap these functions to off-load the argument changes elsewhere. My code is:

function KWArgs(obj) {
    for (let key in obj) {
        this[key] = obj[key];
    }
}

function kwargFn(fn) {
    return function (...args) {
        let kwargs = args[args.length - 1] || {};
        if (kwargs instanceof KWArgs) {
            args.pop();
        } else {
            kwargs = {};
        }
        return fn(args, kwargs);
    }
}

Here's an example of how I use it:

let filter = kwargFn(function* (args, {key='id', value=undefined}) {
    for (let item of args) {
        if (item[key] == value) {
            continue;
        }
        yield item;
    }
});

let values = filter({}, {id: 1}, new KWArgs({value: 1}));

I personally think that new KWArgs makes this solution a bit more horrible than I'd like, and so is there a better way I can achieve the same result? I'm also looking for any and all feedback on the rest of my code too.

\$\endgroup\$
2
\$\begingroup\$

Why not just add a function wrapper:

function k(obj) {
  return new KWArgs(obj);
}

let values = filter({}, {id: 1}, k({value: 1}));

If you're not using jQuery you might even call your function $

In your KWArgs constructor I would use Object.assign rather than enumerating the keys myself: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.