10

While reading about IronJS, I can across the article here http://ironjs.wordpress.com/

In it is the following:

*Context sensitive function keyword

In case you didn’t know, these two functions are not identical:

(function bar() { })  

function foo() { } 

Finding out the difference I’ll leave as an exercise to the reader.

Can some explain the difference here?

Brad
  • 146,404
  • 44
  • 300
  • 476
Gaz
  • 3,455
  • 5
  • 23
  • 33
  • 3
    One is a **function declaration** and the other is a **named function expression**. *Finding out which is which I'll leave as an exercise to the reader.* ;) – Felix Kling Jun 22 '11 at 20:39
  • 3
    If the reader reads kangax on NFE (named function expressions) they *should* be enlightened. http://kangax.github.com/nfe/ – Sean Vieira Jun 22 '11 at 20:41
  • @SeanVieira Thanks for the link, look like a good article! – Gaz Jun 22 '11 at 20:49
  • related: [Explain JavaScript's anonymous function syntax](http://stackoverflow.com/q/1634268/1048572) and [var functionName = function() {} vs function functionName() {}](http://stackoverflow.com/q/336859/1048572) – Bergi Jul 16 '14 at 21:40

4 Answers4

9
function foo() { }

Creates a function

(function foo(){ })

Returns a function object. You can also use:

(function foo(){ })(bar)

And make an anonymous function. (Note that the (bar) means that within that function this refers to the bar instance.)

Check out this other SO post for more information.

Community
  • 1
  • 1
Brad Christie
  • 96,086
  • 15
  • 143
  • 191
  • 1
    Did you mean *immediate* or *self-invoking* function in the end? Although you execute it immediately, it has still a name, so it is not anonymous. `(function(){ })` or `(function(){ })(bar)` would be. – Felix Kling Jun 22 '11 at 20:54
6

I am guessing the difference is that the first one is not visible to the global scope and the latter is visible globally.

Amir Raminfar
  • 32,592
  • 7
  • 83
  • 119
  • This is correct, but that form isn't very useful. More useful is `(function(){}())` or `(function(){})()` which makes the function invisible to the global scope, but runs immediately. – timw4mail Jun 22 '11 at 20:37
  • 2
    But why? (I know but you probably should explain it.) – Felix Kling Jun 22 '11 at 20:38
4

To expand on @Amir's answer:

js>(function bar() {})(3)
js>bar
console:1       ReferenceError: bar is not defined
js>function foo() {}
js>foo
function foo() {
}

(code executed in jsdb)

These are named functions, and if you don't put parentheses around the function definition, they become part of the local scope. function foo() {} becomes available for use later, but bar does not.

As a third example:

var x = function baz() {};

If you run this:

js>var x = function baz() {}
js>baz
console:1       ReferenceError: baz is not defined

You'll note that it's the similar case as (function baz(){})(3).

The case of

function foo() {}

is special, the Javascript interpreter sees that form and says, "Oh, you're trying to define a function named "foo" in the local scope."

As for why a named function is useful even if it doesn't get defined in the local scope -- the named function is visible from the scope of the function itself:

js>var x = function fact(n) { return n*((n < 2) ? 1 : fact(n-1)); }
js>x(3)
6
js>fact
console:1       ReferenceError: fact is not defined

Here we have a factorial function named "fact", but the name "fact" is only visible inside the scope of the function itself.

Jason S
  • 171,795
  • 155
  • 551
  • 900
  • +1 for so much examples. Named function expressions should be avoided anyway. If I remember correctly it caused some weird behaviour in older IE versions (namely creating *two* versions of the same functions with two different names). – Felix Kling Jun 22 '11 at 21:06
2

The first function is a named anonymous function (yeah). The expression evaluates to a Function. The second one defines a named function and returns undefined.

Jakub Lédl
  • 1,775
  • 2
  • 16
  • 26