tags:

views:

117

answers:

4

Suppose we are inside a function and not in the global namespace.

function someGlobalFunction() {
  var utilFunction1 = function() {
  }

  function utilFunction2 () {
  }

  utilFunction1();
  utilFunction2();

}

Are these synonymous? And do these functions completely cease to exist when someGlobalFunction returns? Should I prefer one or the other for readability or some other reason?

+12  A: 

Largely.

utilFunction1 will only be available after it has been declared. utilFunction2 is hoisted to the top of the function, so can be used before it is defined.

function someGlobalFunction() {
  utilFunction1(); // Error: untilFunction1 is undefined :(
  utilFunction2(); // Works

  var utilFunction1 = function() {
  }

  function utilFunction2 () {
  }
}

Unless they are trapped in a closure, they will cease to exist when someGlobalFunction returns.

I prefer to use the method used to declare utilFunction2, but it's up to you.

Matt
+1 - Looks like you have everything covered.
ChaosPandion
It could also be noted that the first is a FunctionExpression while the latter one is a FunctionDeclaration.
Sean Kinsey
+4  A: 

Yes, they are quite different:

  • utilFunction1 has no name, so if it throws an exception, your debugging tool will only tell you that an anonymous function threw up
  • utilFunction2 will be available in the scope of the function even before that line is reached (as fletcher noted)
  • using the utilFunction2 notation can cause odd behavior in certain circumstances in IE.

Ex:

if (true) {
  function utilFunction() {
    return true;
  }
} else {
  function utilFunction() {
    return false;
  }
}

utilFunction(); // returns false in IE, true everywhere else

IE takes the function scope issue to the extreme, effectively evaluating functions, even if there is no code path to them!

jimbojw
Putting a function statement inside an `if` or other non-function-block is not valid in ECMAScript; browser behaviour varies wildly. Avoid!
bobince
+2  A: 

The following link explores the subtleties (often bugs) between various ways of defining functions.

http://yura.thinkweb2.com/named-function-expressions/

trinithis
Just so you know, none of those were a named FunctionExpression.That would have the form of `var foo = function bar(){}`
Sean Kinsey
Some are named in the article. The second code example in the section named "Named function expressions" has some for instance.
trinithis
+1  A: 

Congratulations! You've found the situation where Function Hoisting gets involved.

var foo = function() { };

is quite different than

function foo() { };

For all the reasons noted elsewhere, plus one.

The second example will be "hoisted" - it will be available anywhere within the current closure (usually the current function). Even before it's declared within said closure.

Something like this would work:

function foo() {
    bar();
    function bar() { alert('baz'); }
}

Whereas something like this would most definitely not:

function foo() {
    bar();
    var bar = function bar() { alert('baz'); };
}

You get an error in this second example, because bar has not been defined yet. If you swap the two lines in the function foo, that example will work.

Douglas Crockford advocates using this second method, because it doesn't contain a hidden behavior like hoisting - your code does exactly what it says it'll do, no tricks involved.

warfangle