0

Recently I learned about the differences between these three things:

var a = function() { ... };

function a() { ... };

var a = (function() { ... })(); 

However, I'm trying to figure out what makes the function expression work the way it does when its parsed. That is, as far as I understand, if I included (function() {...})(); on a line in my Javascript code, it would immediately execute. Is this true?

If so, what happens when the parser sees that? Is it because the function is wrapped in the parentheses or because of the appended parenthesis, or something else? I read on the MDN docs on Table 3.7 that () and new are one way to call/create a new instance of something, so could I achieve the same result of (function() {...})(); with new Function(...);? (Disregarding the fact that new Function(); takes strings).

josh
  • 6,518
  • 3
  • 28
  • 49
  • 2
    What do you mean by "at a lower/language level?" – Robert Harvey Jun 25 '14 at 15:48
  • The third is an example of IIFE or immediately-invoked function expression. Try Googling it, or self-invoking function. – j08691 Jun 25 '14 at 15:48
  • Do you want to know how the parser parses the JavaScript code? – VisioN Jun 25 '14 at 15:48
  • http://stackoverflow.com/questions/336859/var-functionname-function-vs-function-functionname and http://stackoverflow.com/questions/8228281/what-is-this-iife-construct-in-javascript – epascarello Jun 25 '14 at 15:49
  • [`Function`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) constructor creates a function from string (somehow like evil `eval`). For example, `new Function('x', 'alert(x)')`. – Oriol Jun 25 '14 at 15:50
  • As VisioN alludes to, this is mostly just a parsing thing. A line starting `function ...` (with no tokens left over from previous parsing) is a function declaration (and will be hoisted)`. Anywhere else that `function` appears where an expression would be permitted, it's a function expression. – Alnitak Jun 25 '14 at 15:50
  • @VisioN yes, and Robert Harvey, I want to know how the parser parses this specific Javascript code. I know that it's a function expression, but that is kind of meaningless to me because I would like to know what actually happens rather than just being told that it happens. – josh Jun 25 '14 at 15:52
  • 1
    I suppose you could decompile the browser. Language parsing is a fairly well-known technique. – Robert Harvey Jun 25 '14 at 15:53
  • @RobertHarvey yeah, and a fairly easy one. I would rather get deep to the open source V8. – VisioN Jun 25 '14 at 15:56
  • Operators expects operands, so the parser interprets the function as the required operand, and as such, as part of an expression. – cookie monster Jun 25 '14 at 16:06
  • It's just a function call, nothing more, nothing less. There is nothing special about it, it just looks weird since the function definition is inlined. But at the end, it's not different from `var a = function(){}; a = a();` – Felix Kling Jun 25 '14 at 16:11

1 Answers1

1

if I included (function() {...})(); on a line in my Javascript code, it would immediately execute. Is this true?

Yes. It's called an immediately executed function expression.

Is it because the function is wrapped in the parentheses or because of the appended parenthesis, or something else?

The wrapping parentheses are of no significance to the execution, you could in fact omit them (when you use the result in another expression, to avoid the syntactic ambiguity with a function declaration) or place them differently. However, the "appended parenthesis" are just a plain function call: anything_that_resolves_to_a_function()

I read on the MDN docs on Table 3.7 that () and new are one way to call/create a new instance of something.

Yes. You shouldn't use new function() { … } though.

so could I achieve the same result of (function() {...})(); with new Function(...);?

No. The Function constructor is a completely different beast.

Community
  • 1
  • 1
Bergi
  • 513,640
  • 108
  • 821
  • 1,164
  • 1
    Unless I misunderstand what you're saying, the wrapping parentheses _are_ significant because they're what make it an expression instead of a declaration. You _can't_ just write `function f() { } ()`. – Alnitak Jun 25 '14 at 15:56
  • @Alnitak: OP is assigning to `var a`, so it's an expression anyway. It makes a difference only if it the top expression of an expression statement. – Bergi Jun 25 '14 at 16:03
  • 2
    I think you've lost some context in your answer - sure, `var a = ...` is definitely an expression, but you don't refer to that, and the only previous use of `function` in your answer is `(function() { ... })()` which emphatically _does_ need the wrapping parentheses. – Alnitak Jun 25 '14 at 16:04
  • Although I now know what you meant, I think your answer is still unclear - it still looks like you're referring to the earlier `(function() { ... })()` and not the omitted part of the OP's question. – Alnitak Jun 25 '14 at 16:13
  • Disregarding variable assignment, i.e. this function just runs without regard to what it returns, what you're saying is it is the appended parenthesis that call the function immediately? – josh Jun 25 '14 at 16:14
  • 1
    @JoshuaSmock yes - the appended parentheses invoke the function (expression), and like a normal function call can also include parameters. – Alnitak Jun 25 '14 at 16:16
  • @JoshuaSmock although Bergi doesn't mention it, you can also just do `+function(){...}()` - the `+` operator is another way to tell the parser that what follows is an expression rather than a declaration. – Alnitak Jun 25 '14 at 16:19
  • Okay, that makes sense. That means that as long as my function returns something, it'll be a valid expression and the parser will parse it immediately. – josh Jun 25 '14 at 16:23
  • @JoshuaSmock it doesn't even need to return something - you can write an expression on a line all by itself (e.g. `1 + 2;`) and the parser will happily evaluate the expression _but discard the result_. Also, a function that doesn't `return` a value implicitly does `return undefined`. – Alnitak Jun 25 '14 at 16:24
  • @JoshuaSmock: It's not about `return`ing anything (the parser doesn't care about that), it's about *using the result* (whatever it is, might even be `undefined`) so that an expression is expected. – Bergi Jun 25 '14 at 16:25
  • Great, that clears up my question. Thank you both! Bergi, if you include the parts about expressions in your answer I'll accept it. – josh Jun 25 '14 at 16:31