new Function()

By  on  

Douglas Crockford once said that JavaScript was the only language developers didn't need to learn to use.  That's as true a statement as you'll hear when it comes to programming.  We all sort of stumbled into JavaScript, mostly due to JavaScript frameworks which made JavaScript magical and easy.  "Anonymous function?  No idea what that is but the example looked like that so that's what I do."

One thing you may not know about JavaScript functions is that you can pass new Function() the function's body in a string.  It isn't something you'd do often but it can be useful

The JavaScript

Here's the basic usage of new Function:

var myFunction = new Function('users', 'salary', 'return users * salary');

The last argument to Function is the function body as a string, and the previous arguments represent different arguments to the function.  Fairly easy, right?

The question is:  what is the use case for this, instead of the tradition function myFnName() and anonymous function definitions? Andrea Giammarchi believes that this pattern is the best way to get the global within NodeJS and the browser:

(function(win) {
	
	// Do something with the global

})(Function('return this')());

If you've used the new Function pattern before, let me know what you've used it for.  I'd love to hear about it!

Recent Features

Incredible Demos

Discussion

  1. Quick question: Is there any reason you wouldn’t just do this to get the global:

    (function(global) {
      // global is now the global 
    })(this);
    

    Does strict mode restrict this somehow? Or does the Function constructor always bind ‘this’ to the global object?

    • depending on where the closure get’s executed ‘this’ may not be ‘window’. Using the Function constructor guarantees that ‘this’ will be window

  2. One classic use of the Function constructor is in JS templating for compiling templates into reusable functions. I think John Resig’s micro templating started it all http://ejohn.org/blog/javascript-micro-templating/

  3. Quotes Douglas Crawford. Then proceeds to discuss the benefits of obscure functionality in the language. (eyes roll)

    anti patterns :
    Isn’t that a bit of an eval() ?
    Are you not breaking the scope properties that make javaScript great and give it recognizable patterns without class?

  4. Nir Leibovitch

    1. Creating dynamic functions on the fly.

    You can, for example, let a savvy end-user define script hooks to be executed when
    triggered by an event.

    2. Parsing script without executing it.

    Passing wrong syntax to the Function constructor will throw a syntax error, but
    will not execute it unless you call the resulting function object. (this opposed
    to eval, which will always execute the passed script).

    Building on the example above, you can alert your end-user if his syntax is
    wrong.

    3. and most importantly, you can hide your local variables from the end-user
    script.

    The function objects created by the Function constructor have an empty scope
    chain, and the current closure will not be saved in them.
    Basically, you get nothing but the global object.

    Continuing our example, even script with correct syntax can be problematic.

    for example, consider the following code:

    (function() {
      // my scope
      var a = 'my a';
    
      // test hook
      /* ... */
      // run hook
      new Function("a = 'user a'; var b = 'user b''")();
    
      console.log(a); // 'my a'
      console.log(b); // ReferenceError: b is not defined
      console.log(window.a) // 'user a'
      console.log(window.b) // ReferenceError: b is not defined
    })();
    

    A simple mistake as forgetting a `var` will not cause the outer scope’s
    local variables to change, but instead go directly to the global scope.

    This is why Function(‘return this’)() will return the global object.

    So why don’t we always use the wonderful Function constructor ?
    Because it’s less efficient than declaring functions normally.

    Hope I managed to answer your question.

  5. Nir Leibovitch

    @Andrew Gaspar
    while putting the following code into the global scope will work

    (function(global) {
      // global is now the global
    })(this);
    

    Assume that you need the global object in a function within an object (or an object constructor)

    obj = {
      a: function(){
        (function(global){console.log(global)})(this);
      }
    }
    obj.a(); // Object {a: function}
    

    if you use the Function constructor, you can get the global object in this case

    obj = {
      a: function(){
        (function(global){console.log(global)})(Function('return this;')());
      }
    }
    obj.a(); // Window {...}
    
  6. Here is one of the possible solutions: http://krasimirtsonev.com/blog/article/Javascript-template-engine-in-just-20-line (template engine in 20 lines)

  7. I meant “possible use cases” ;) and as Nick said I also found the concept in John Resig’s blog.

  8. There’s a thread on Stack Overflow that discusses the legitimate usages of the Function constructor: http://stackoverflow.com/questions/3026089/legitimate-uses-of-the-function-constructor

  9. Jos de Jong

    I use new Function() since some time in math.js (http://mathjs.org) to compile mathematical expressions to JavaScript. This compile step boosted the performance with about a factor 10 (!). A downside is that the code to build up these new Functions is less readable than regular JavaScript.

  10. Daniel

    jQuery used it to parse JSON where the native JSON.parse was missing.

  11. We used it with David Bruant to let users inject behaviours in an existing page (an elevators simulator).

    See http://elevato.rs/

  12. As far as I remember both the Function constructor and eval are not allowed at all on Firefox OS. If that’s the case that `Function(‘return this’)()` will break :\

  13. Pier: Yes you are right. The Firefox OS CSP (Content Security Policy) does not allow new Function() because it’d allow the execution of arbitrary strings as code (thus making any sort of code review useless and almost inviting privilege escalation problems).

    In more detail: https://developer.mozilla.org/en-US/Apps/CSP

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!