tags:

views:

723

answers:

8

What's the difference between:

function sum(x, y) {
  return x+y;
}

// and 

var sum = function (x, y) {
    return x+y;
}

Why is one used over the other?

+1  A: 

Read this answer, it has everything you need to know and more :)

Vinko Vrsalovic
They're both the same wrt. closures.
Daniel James
Wouldn't it be better to simply have the correct answer to this question??
AnthonyWJones
This question has nothing to do with closures, and even if it did Daniel James is right.
Prestaul
+3  A: 

The first one is a named function statement, the second one assigns an anonymous function expression to a variable.

The function statement is added to its scope immediately - you don't need to run it before being able to call it, so this works:

var y = sum(1, 2);

function sum(x, y) {
   return x + y;
}

But the function expression is only assigned to the variable when the code is executed, so this doesn't work:

// Error here because the function hasn't been assigned to sum yet.
var y = sum(1, 2);

var sum = function(x, y) {
   return x + y;
}

An advantage of the expression form is that you can use it to assign different functions to the expression at different points - so you can change the function, or use a different one under different conditions (such as depending on the browser being used).

An advantage of a named function statement, is that debuggers will be able to display the name. Although, you can name function expressions:

var sum = function sum(x, y) {
   return x + y;
}

But this can be confusing since the two names are actually in different scopes and refer to different things.

Daniel James
A: 

They mean the exact same thing. It's just syntactic sugar. The latter is IMO more revealing of what JavaScript is really doing; i.e. "sum" is just a variable, initialised with a function object, which can then be replaced by something else:

$ js
js> function sum(x,y) { return x+y; }
js> sum(1,2);
3
js> sum=3
3
js> sum(1,2);
typein:4: TypeError: sum is not a function
js> sum
3
niXar
+15  A: 

The first is known as a named function where the second is known as an anonymous function.

The key practical difference is in when you can use the sum function. For example:-

var z = sum(2, 3);
function sum(x, y) {
    return x+y;
}

z is assigned 5 whereas this:-

var z = sum(2, 3);
var sum = function(x, y) {
    return x+y;
}

Will fail since at the time the first line has executed the variable sum has not yet been assigned the function.

Named functions are parsed and assigned to their names before execution begins which is why a named function can be utalised in code that preceeds its definition.

Variables assigned a function by code can clearly only be used as function once execution has proceeded past the assignment.

AnthonyWJones
+9  A: 

The first tends to be used for a few reasons:

  1. The name "sum" shows up in the stacktrace which makes debugging easier in many browsers.
  2. The name "sum" can be used inside the function body which makes it easier to use for recursive functions.
  3. function declarations are "hoisted" in javascript, so in the first case, the function is guaranteed to be defined exactly once.
  4. Semicolon insertion causes

    var f = function (x) { return 4; }

    (f)

    4 to be assigned to f.

There are a few caveats to keep in mind though. Do not do

  var sum = function sum(x, y) { ... };

on IE 6 since it will result in two function objects being created. Especially confusing if you do

  var sum = function mySym(x, y) { ... };

According to the standard, function sum(x, y) { ... } cannot appear inside an if block or a loop body, so different interpreters will treat

  if (0) {
    function foo() { return 1; }
  } else {
    function foo() { return 2; }
  }
  return foo();

differently. In this case, you should do

  var foo;
  if (0) {
    foo = function () { return 1; }
  } ...
Mike Samuel
Good point about the if statement. But I don't think it's true that the function is guaranteed to be defined exactly once. (Or maybe I misunderstood you?)
Daniel James
I'm not sure I understand what you're saying in point 4..
Kip
I don't understand the exactly once statement either. Different definitions of the same function name may be present, the last definition wins.
AnthonyWJones
Have you got any reference for you statement regarding assigning a named function to a variable? As far as I can see only one function is created.
AnthonyWJones
If function foo() {}appears in a program/function_body production, then hoisting should cause one function object to be created each time the containing program is entered.It's possible that an out of memory error could prevent allocation but that should not be an observable failure.
Mike Samuel
Sorry, point 4 is a bit garbled. I meant that var f = function f() { return 4; } /* newline here */ (0);is interpreted as var f = (function f() { return 4; })(0);
Mike Samuel
+1  A: 

The difference is...

This is a nameless function

var sum = function (x, y) {
    return x+y;
}

So if you alert(sum); you get "function (x, y) { return x + y; }" (nameless) While this is a named function:

function sum(x, y) {
        return x+y;
}

If you alert(sum); now you get "function sum(x, y) { return x + y; }" (name is sum)

Having named functions help if you are using a profiler because the profiler can tell you function sum's execution time...etcetera instead of an unknown functions's execution time...etcetera

A: 

here's an other example: function sayHello(name) { alert('hello' + name) }

now,suppose you want modify onclick event of a button, such as it says "hello world"

you can not write:

yourBtn.onclik = sayHello('world'), because you must provide a function reference.

then you can use second form: yourBtn.onclick = function() { sayHello('workld'); }

Ps: sorry for my bad english!

stefano m
+2  A: 

The two code snippets you've posted there will, for almost all purposes, behave the same way.

However, the difference in behaviour is that with the second variant, that function can only be called after that point in the code.

With the first variant, the function is available to code that runs above where the function is declared.

This is because with the second variant, the function is assigned to the variable foo at run time. In the first, the function is assigned to that identifier foo at parse time.

More technical info

Javascript has three ways of defining functions.

  1. Your first example is a function declaration. This uses the "function" statement to create a function. The function is made available at parse time and can be called anywhere in that scope. You can still store it in a variable or object property later.
  2. Your second snippet shows a function expression. This involves using the "function" operator to create a function - the result of that operator can be stored in any variable or object property. The function expression is powerful that way. The function expression is often called an "anonymous function" because it does not have to have a name,
  3. The third way of defining a function is the "Function()" constructor, which is not shown in your original post. It's not recommended to use this as it works the same way as eval(), which has its problems.
thomasrutter