views:

142

answers:

3

Hi, today I've read we have a way of declaring the function by Function constructor. But I never seen the actual implementation that uses Function constructor in real. So I would like to ask, are there any circumstances that we can get benefit by using Function constructor as opposed to using function() declaration? And what are the hidden differences of between?(if there is any)

Function Constructor

var func = new Function("x", "y", "return x*y;"); // pass the context by String

function():

var func = function(x, y){ return x*y; }

Thanks

+2  A: 

Well, the obvious difference when working with strings is that you have the option of meta-programming, by constructing the string at runtime (the same as you could with eval). However, this is double edged, and arguably leads into a range of other problems with literal concatenation (injection), and perhaps simply complexity. If you don't need the string version, I wouldn't use it to be honest.

A side benefit of the regular (non-string) version is that most javascript minifiers (or obfuscators) will know what to do with it. This seems unlikely for the string, i.e. they'll leave it "as is" (not minified or obfuscated).

Marc Gravell
Can you give an example to the problems meta programming?
Braveyard
@Braveyard - done *right* meta programming is fine; but it is also a great way to open up xss holes if done wrong. For example, if the user can abuse the string to get other users to post their cookies to you.
Marc Gravell
+2  A: 

If you're writing a Javascript parser and are interpreting a string as a function then you could use a function constructor. EG if you are given:

"function(x){return x+2}"

And you have some sort of lexical parser and it finds that substring is indeed a function, to translate it into a real function you would use new Function and add it to your tree.

Otherwise there really isn't much of a use that I can think of.

meder
+6  A: 

The Function constructor is a form of eval, which should generally be avoided (it's slow and considered insecure). There is really no benefit to using the Function constructor over the built in function statement unless you want to construct a function from dynamic components, which is pretty rare. There are legitimate uses for this form, however most of the time it's used unnecessarily which is why it's looked down upon and generally avoided.

Also, functions created with the function will not keep a reference to the environment they were defined in (the closure). When executed, they will pull those variables directly from the global scope.

var f, a;
(function () {
   var a = 123;
   f = new Function("return a");
})();

f(); //undefined

a = "global"
f(); // "global"

Whereas regular functions do keep a reference to the environment in which they were defined:

var f;
(function () {
   var a = 123;
   f = function () { return a; }
})();
f(); //123
CD Sanchez
I am wondering what they were thinking when building this `Function` object.
Braveyard
Well it's pretty useful for something like the js1k competition :-)
Pointy
@Daniel, Note that the "slow" part would be only the function *compilation*, after a function object is constructed, it will behave exactly the same as if it was created with a `FunctionDeclaration` or a `FunctionExpression`.
CMS
@CMS: Yes, of course. But since we're on the topic of the constructor I thought it would be a good idea to include the possible performance implications of using the constructor method. This highly unscientific test shows that the difference is non-negligible: http://jsperf.com/function-constructor-vs-function-literal Though I admit that in the grand scheme of things it probably won't be noticed by the user.
CD Sanchez
That only tests the difference in defining the function, not running it. That is the whole point. Dynamically constructing a function can improve performance by removing unneeded conditional checks, loop unrolling, etc. The cases where such fine tuning is needed are rare but they do exist. Also there is something to be said for creating a function that does not capture a bunch of unneeded variables in a closure.
MooGoo
@MooGoo: Yes... that was the intention of the test. It has been established that there is no difference in execution times. This question is concerned with the different methods of *declaring* a function.
CD Sanchez
I don't think the differences in performance regarding defining a function was ever in doubt. I just feel it is important to stress that `new Function != eval` when it comes to speed. Continually redefining a function in a loop with the `Function` constructor to test for its performance is no different than just using `eval` directly, but it is misleading because that is *never* how the Function constructor would be used.
MooGoo