8

I sometimes see people doing this Function('alert("hi")') and sometimes they do new Function('alert("hi")')

Is there a difference between the two?

user594284
  • 83
  • 1
  • 4

4 Answers4

5

The spec (page 127) says they're identical.

15.3.1.1 Function (p1, p2, … , pn, body)

When the Function function is called with some arguments p1, p2, … , pn, body (where n might be 0, that is, there are no “p” arguments, and where body might also not be provided), the following steps are taken:

  1. Create and return a new Function object as if the standard built-in constructor Function was used in a new expression with the same arguments (15.3.2.1).

However, you should avoid the Function constructor at all costs.
It needs to eval the string you pass to it; eval is evil, and slow too.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
1

There is only one usage of new Function. It is this:

var constructor = new Function;

// then this 

constructor.prototype = { 
    //...  stuff
};

// OR

constructor.prototype = new someOtherThing;

// then

var obj = new constructor;

Basically you can use new Function if you want to create an object constructor with an empty constructor that only uses inheritance.

If you want a function to do anything then don't use Function at all.

Raynos
  • 166,823
  • 56
  • 351
  • 396
  • How is that better than `function(){}`? – SLaks Jan 28 '11 at 19:26
  • 1
    @SLaks it's a matter of style. But it's still the only valid usage of `new Function` – Raynos Jan 28 '11 at 19:27
  • Believe it or not, jQuery uses `new Function(...)`. – SLaks Jan 28 '11 at 19:28
  • @SLaks That's just using eval without using eval. Is there any argument for new Function vs eval ? – Raynos Jan 28 '11 at 19:32
  • 3
    @Raynos, I would say the ´Function´ constructor is safer than ´eval´, because it uses a completely new variable/lexical environment (you have access only to identifiers declared in the global scope, or within the function itself, and not to the scope of the caller). – Christian C. Salvadó Jan 28 '11 at 19:46
  • @CMS: Yeah, after realizing that, I noted it, then decided to delete. My example was embarrassingly flawed. :o) – user113716 Jan 28 '11 at 19:49
  • @CMS that prints overwritten by Function for me in chrome. It's a poor example of what your trying to show – Raynos Jan 28 '11 at 19:58
  • Raynos: That's completely my fault. He was pointing out the terrible flaw in my example, which I deleted. Sorry for the confusion. I think [this example](http://jsfiddle.net/GJXAk/1/) illustrates what @CMS is saying. – user113716 Jan 28 '11 at 19:59
  • @patrickdw that example is safe anyway because of invoking `new` on that function creates a unique `this` scope. This illustrates it more clearly: http://jsfiddle.net/Raynos/GJXAk/4/. @CMS Thanks for the explanation though. – Raynos Jan 28 '11 at 20:05
  • Raynos: My example made the same mistake as the first, in that it didn't execute the function. Ugh! This would be the correct one. http://jsfiddle.net/GJXAk/5/ – user113716 Jan 28 '11 at 20:08
  • Raynos: I think I see what you're saying. – user113716 Jan 28 '11 at 20:12
0

To answer your question: Function(...) and new Function(...) are exactly the same according to the ECMA5 specs.

To shed some light as to when and where this should be used, the answer is rarely. I know of one situation where we have used Function(...), and it was when creating custom ASP.NET server controls. We often have something to the effect of [ServerControl].OnClientClick, which specifies a JavaScript string (on the server side) that should be ran on the client side when the click event occurs. We then put the JS string into a Function and call it when specific conditions have been met. This also allows us to invoke the .call(...) function to set the context and to pass in the event parameters as if the JS were being called from an onclick attribute.

Andacious
  • 1,162
  • 10
  • 17
0

Invoking the Function constructor as a function (without using new operator) has the same same effect as invoking it as constructor.

That means it is same to code if you do it:

var result1 = new Function('a', 'b', 'return a + b')
var result2 = Function('a', 'b', 'return a + b')

result1 and result2 are same.

Predrag Davidovic
  • 1,411
  • 1
  • 17
  • 20