HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Python like kwargs

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
kwargslikepython

Problem

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.

Solution

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

Code Snippets

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

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

Context

StackExchange Code Review Q#156137, answer score: 2

Revisions (0)

No revisions yet.