Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Legitimate uses of the Function constructor

As repeatedly said, it is considered bad practice to use the Function constructor (also see the ECMAScript Language Specification, 5th edition, § 15.3.2.1):

new Function ([arg1[, arg2[, … argN]],] functionBody) 

(where all arguments are strings containing argument names and the last (or only) string contains the function body).

To recapitulate, it is said to be slow, as explained by the Opera team:

Each time […] the Function constructor is called on a string representing source code, the script engine must start the machinery that converts the source code to executable code. This is usually expensive for performance – easily a hundred times more expensive than a simple function call, for example. (Mark ‘Tarquin’ Wilton-Jones)

Though it's not that bad, according to this post on MDC (I didn't test this myself using the current version of Firefox, though).

Crockford adds that

[t]he quoting conventions of the language make it very difficult to correctly express a function body as a string. In the string form, early error checking cannot be done. […] And it is wasteful of memory because each function requires its own independent implementation.

Another difference is that

a function defined by a Function constructor does not inherit any scope other than the global scope (which all functions inherit). (MDC)

Apart from this, you have to be attentive to avoid injection of malicious code, when you create a new Function using dynamic contents.

That said, T.J. Crowder says in an answer that

[t]here's almost never any need for the similar […] new Function(...), either, again except for some advanced edge cases.

So, now I am wondering: what are these “advanced edge cases”? Are there legitimate uses of the Function constructor?

like image 706
Marcel Korpel Avatar asked Jun 11 '10 20:06

Marcel Korpel


People also ask

What is the use of function constructor?

A constructor is a special function that creates and initializes an object instance of a class. In JavaScript, a constructor gets called when an object is created using the new keyword. The purpose of a constructor is to create a new object and set values for any existing object properties.

Can we use constructor in function?

That's the main purpose of constructors – to implement reusable object creation code. Let's note once again – technically, any function (except arrow functions, as they don't have this ) can be used as a constructor. It can be run with new , and it will execute the algorithm above.

Why do we use constructor in JavaScript?

A constructor enables you to provide any custom initialization that must be done before any other methods can be called on an instantiated object. The ValidationError class doesn't need an explicit constructor, because it doesn't need to do any custom initialization.

What is the use of constructor in TypeScript?

A constructor is a special function of the class that is responsible for initializing the variables of the class. TypeScript defines a constructor using the constructor keyword. A constructor is a function and hence can be parameterized. The this keyword refers to the current instance of the class.


2 Answers

NWMatcher — Javascript CSS selector and matcher, by Diego Perini — uses Function constructor (1, 2, 3, 4, etc.) to create ("compile") highly-efficient versions of selector matchers.

The benchmark (which I just ran on Chrome 5) speaks for itself:

alt text

Note the difference between NWMatcher and Sizzle, which is a very similar selector engine, only without function compilation :)

On a side note, ECMAScript 5 doesn't throw any errors on invocation of Function. Neither in strict, nor in "standard" modes. Strict mode, however, introduces few restrictions on presence of identifiers such as "eval" and "arguments":

  • You can't have declare variables/functions/arguments with such names:

    function eval() { } var eval = { }; function f(eval) { }  var o = { set f(eval){ } }; 
  • You can't assign to such identifier:

    eval = { }; 

Also note that in strict mode, eval semantics is slightly different from that in ES3. Strict mode code can not instantiate variables or functions in the environment from which it was called:

 eval(' "use strict"; var x = 1; ');  typeof x; // "undefined" 
like image 134
kangax Avatar answered Sep 17 '22 17:09

kangax


jQuery uses it to parse JSON strings when a JSON parser object is not available. Seems legit to me :)

        // Try to use the native JSON parser first         return window.JSON && window.JSON.parse ?             window.JSON.parse( data ) :             (new Function("return " + data))(); 
like image 29
harpo Avatar answered Sep 20 '22 17:09

harpo