Seeking a Function Object with implicit return — similar to Arrow Function

Viewed 101

Arrow functions provide the convenience of implicit return. I am trying to achieve something similar via the Function Object but couldn't find anything. Essentially I need to evaluate an expression using the Function Object but get the value of the expression assuming the semantics of

`() => ${expression}`

result in implicit return. The function object itself is created as

new Function(expression)

The expression in this for example can be "new Date()". Workaround is to have the expression specified as "return new Date()" but it's less convenient for the person providing the expression.

1 Answers

So the idea is to force a return value on an expression that doesn't have one.

Here's the beginning of a possible solution that extends Function to another class named FWithReturn

FWithReturn simply prepends the return when none exists, then passes along to the Function constructor.

This example is for a simple expression with or without a return, or a complex expression with a return.

Note: This method fails to return a value, for an IIFE like (function(){ return 42; })().

class FWithReturn extends Function {
  constructor(...args) {
    let fnBody = args[args.length - 1].replace(/\s/g, '');
    
    // detect IIFE (begins with '(', includes ')()')
    let isIIFE = Boolean(fnBody.match(/^\(/) &&
        fnBody.match(/\)\(\)/));
    
    if (isIIFE || !fnBody.includes("return")) {
      args[args.length - 1] = "return " +  args[args.length - 1];
    }
    super(...args);
  }
}

// simple expression
const a = new FWithReturn("a", "b", "a + b");
addRes('FWithReturn("a", "b", "a + b")', a, a(10, 5));

// simple expression with return
const b = new FWithReturn("a", "b", "return a + b");
addRes('FWithReturn("a", "b", "return a + b")', b, b(100, 50));

// compound expression with return
const c =
  new FWithReturn("let d = new Date(); return d.toLocaleTimeString();");
addRes(
  'FWithReturn("let d = new Date(); return d.toLocaleTimeString();"', c, c());

// IIFE that returns a value
const d = new FWithReturn("(function(){ return 42; })();");
addRes('FWithReturn("(function(){ return 42; })();")', d, d());
<pre id="result">Results:

</pre>
<script>
  const result = document.getElementById('result');

  const addRes = function(fn, newFn, val) {
    result.innerHTML +=  fn + '\n' + newFn + '\nReturns: ' +
      val + '\n\n';
  }
</script>

Related