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
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:
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.
Additional notes to Cristian Sanchez' posting.
You can never access local scope vars within a 'Function'-Evaluation.
Lets see the difference between Function and eval.
Function-Example:
The Function-Constructor doesn't know anything about the local scope, because it creates a new isolated Scope underneath the window/global-Object - not at the position where it is - that is the main-difference to eval.
Eval-Example:
'eval' has access to the local vars. Even if you scope the whole thing.
In the following example f() throws an error - "a" is undefined in his own (and global) scope. The Function-Constructor has its own special scope without knowing anything outside - except his parent scope - the window/global-object.
If you want to use local vars, pass it as parameters to the Function-Constructor inside the inner scope!
or
You can execute Function directly with call/apply, too (no "new" needed).
By the way, it's always recommend, setting the strict mode, to enable correct ES5 behaviour.
With strict-mode 'this' is (correctly) undefined by default - until you bind an object.
If you want, you can bind 'this' explicitly
Of course you can bind any function/class-object to extend objects.
Same result with direct call, without 'new' keyword.
Every function/class is created through the the 'Function'-constructor.
So you don't have to write "Function" in your code. You can use the constructor-object, too.
The use of 'Function' is good for example for games, if you have a XMLHttpRequest-Preloader, which loads a very large Javascript-File (5-10 MB bundled scripts), while you want display a loading-bar or something else to the user, instead loading the whole thing with a script-tag, while the user is waiting for page-loading without any visual response.
It does not matter if you load a large script via a script tag, or via Function once on startup. The engine has to load the plain code and evaluate it either way. There are no security aspects, if your(!) code came from a trusted source (your domain) and you know whats inside.
'Function' and 'eval' are only bad with untrusted code (when other users have influence on it) or in loops (slow performance due compiling), but it is totally okay to load & evaluate your own scripts on startup, if the code is the same as in external Javascript-files.
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 constructor 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.
Whereas regular functions do keep a reference to the environment in which they were defined:
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).