Extract function arguments and defaults when using object destructuring

This was such a pain to get working, and the solution isn’t ideal but it works.

I wanted to create an extensible library of functions which could be displayed in a UI. So I created functions like this:

function myFunction({a = '1', b = 2, c = [1,2], d = function(){return 'hi'}} = {}){};

To display the function options in a UI to allow users to call them, I wanted to get all the parameters and their defaults (and not pollute the global scope). I thought it’d be easy. It was not. This is my solution:

function getArguments(f) {
  var t = {};
  (new Function(`with(this) {
    with(new Proxy(this,{
      has(t, p) {return true;},
      get(t, p) {return (p in t ? t : window)[p]}
    })) {
      ${f.toString().match(/^function\s*[^(]*\(\s*{(.*)}\s*=\s*{}/ms)[1]}
    }
  }`)).call(t);
  return Object.entries(t).map(v => ({name: v[0], value: v[1]}))
}

So you can call it like this:

getArguments(myFunction);

And it returns all the arguments and their default values:

Note: it only returns arguments which have defaults.