28

More and more I'm seeing functions being declared like

var foo = function() {

    // things
};

Instead of how I had learned, like

function foo() {

    // things
}

What's the difference? Better performance? Scope? Should I be using this method?

2
  • it's worth noting that in javascript, functions are first-class-citizens. This allows you to pass around behavior just like objects. This is very useful for callbacks and delegation, among other things.
    – Chris Bye
    Aug 14, 2012 at 13:32
  • Scope. The variable name wrapping "//things" is essentially/hopefully preventing name collisions of the "//things" it's wrapping, with other JavaScript (files) included. Another way to think of it is that you have created a namespace "foo".
    – radarbob
    Aug 14, 2012 at 17:49

4 Answers 4

25

var foo = function() {} defines a variable that references an anonymous function.

function foo() {} defines a named function foo.

Either can be passed by name as function parameters and either can be instantiated if the intended use is for OOP.

At the end of the day, which one you use is largely dictated by your specific use-case (Javascript is fun like that ;)). If you end up using the former, I would strongly suggest that you name the function:

var foo = function MY_function() {}. This naming convention helps your debugger callstack not be useless.

5
  • 1
    Got a goof there on function() MY... Aug 13, 2012 at 22:37
  • 1
    @Demian Brecht, and what about var foo = function foo() {...} approach?
    – shabunc
    Aug 16, 2012 at 11:40
  • @shabunc: What about it? It's listed in the last paragraph of my answer. Aug 16, 2012 at 15:10
  • @Demian Brecht, no, actually in last paragraph variable is called foo and function is called MY_function
    – shabunc
    Aug 16, 2012 at 15:12
  • @shabunc: The name doesn't matter. What matters is the value in the callstack. As an example, [NAMESPACE]_[fn name] is the convention used by Mozilla. The name itself doesn't matter as long as your convention is consistent throughout your project. Aug 16, 2012 at 16:31
13

function expression:

//someFunction(); //wouldn't work when uncommented
var someFunction = function(){ alert('yay'); };

The func expression in this case is anonymous but assigned to a var for reference. This is different from a labeled function statement in the following ways:

  • it can't be hoisted (called before it's defined)
  • new someFunction().constructor.name === 'someFunction';//false instances don't get the var name for constructor.name because a reference to the function is assigned to the var but the var, not the function, is tied to the var name

In a labeled function statement:

//someFunction(); //works when uncommented
function someFunction(){ alert('yay'); }
  • hoisting works
  • new someFunction().constructor.name === 'someFunction'; //true the name is tied directly to the function.

Generally speaking there's not really any great reason to do expression to var unless you want calls to fail if things get moved around or you're defining/assigning a method in one line. I actually find hoisting useful for organizing objects with internal func and method definitions at the bottom so I can get to the actual behavior of the object and do one-line public method definitions (by just assigning funcs to this. with the same name) all in one spot for ease of reference. You should always try to use labeled statements for constructors, IMO, so you can identify an object's 'type' via its constructor.

8

Your first example is an expression while the second example is a statement. Defining functions as expressions allows for more flexibility in where the definition can occur, what you can assign it to, that you can pass it as a parameter, etc...

For example:

SomeThing('abc', function(a,b) {return a*b;});

vs...

function tmp(a,b) { 
    return a*b;
}

SomeThing('abc', tmp);

More complex examples would become obcenely complicated without the function expression syntax.

Look at https://stackoverflow.com/questions/111102/how-do-javascript-closures-work

4

The main practical difference is hoisting. For example:

foo(); // alerts 'hello'
function foo() {alert('hello');}

vs

foo(); // throws an error since foo is undefined
var foo = function() {alert('hello');}

Also, this is undefined behavior

function foo(){
  if (true) {
    function bar(){}
  }
  bar();
}

while this is ok.

function foo(){
  if (true) {
    var bar = function(){}
  }
  bar();
}
7
  • 7
    There's absolutely nothing wrong with defining a function inside a function in JS. There's not many places you can't define a function in JS. Aug 13, 2012 at 23:02
  • 2
    @ErikReppen You definitely can't use a function declarations within non-function blocks (like within an if statement). I can't seem to find where I read they can't be used within another function.
    – Austin
    Aug 14, 2012 at 5:59
  • @Austin There's nothing wrong with a function definition within an if statement either!
    – Tim
    Aug 14, 2012 at 10:09
  • @Austin: Perhaps you read it at w3schools? ;) Aug 14, 2012 at 14:28
  • 2
    @ErikReppen Function expressions can be used anywhere. Function declarations can't be. See stackoverflow.com/questions/10069204/…
    – Austin
    Aug 14, 2012 at 17:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.