4

I'm reading this tutorial: http://nathansjslessons.appspot.com/

Inside there's a lessons that says:

// A simple function that adds one
var plusOne = function (x) {
    return x + 1;
};

I'm used to see functions like this:

function myFunction() {
    return x + 1;
};

What's the difference between the first and the second?

Martijn
  • 1,620
  • 9
  • 18
alexchenco
  • 53,565
  • 76
  • 241
  • 413

5 Answers5

5

The only difference is the first function:

var plusOne = function (x) {
    return x + 1;
};

is defined at runtime, whereas another function:

function myFunction() {
    return x + 1;
};

is defined at parse time for the script block.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
Sudhir Bastakoti
  • 99,167
  • 15
  • 158
  • 162
  • it is *declared* at parse time, not defined. – jAndy Nov 13 '11 at 07:42
  • -1 - Everything in JavaScript is evaluated at runtime. There's no separate "parse time". JavaScript is an interpreted language. – Aadit M Shah Nov 13 '11 at 08:56
  • @Aadit: only because JavaScript is interpreted doesn't mean that code execution happens in a single pass; in general, interpretetation will happen in phases, and Sudhir's answer is essentially correct, even his terminology is non-standard – Christoph Nov 13 '11 at 10:03
  • @Aadit - to follow on from what Christoph said, the JavaScript engine definitely makes two passes through the code, a fact easily demonstrated in any browser if you use the function statement `function myFunction()` syntax. Such declarations (along with variable declarations) are "hoisted"; you can call a function declared in that manner from code that appears _before_ it in the script - something that obviously wouldn't work if there was only one pass. You may term the first pass something other than "parse time", but essentially that's what it is. – nnnnnn Nov 13 '11 at 10:16
  • btw, that should have read *even **if** his terminology is non-standard* – Christoph Nov 13 '11 at 10:34
2

Read this post written by @CMS. He does a wonderful job of explaining the difference between a FunctionDeclaration and a FunctionExpression. To quote what he has written:

Functions can be declared in different ways, compare the following:

1- A function defined with the Function constructor assigned to the variable multiply:

  var multiply = new Function("x", "y", "return x * y;");

2- A function declaration of a function named multiply:

  function multiply(x, y) {
     return x * y;
  }

3- A function expression assigned to the variable multiply:

  var multiply = function (x, y) {
     return x * y;
  };

4- A named function expression func_name, assigned to the variable multiply:

  var multiply = function func_name(x, y) {
     return x * y;
  };

To put it simply, the following code can either be a FunctionDeclaration or a FunctionExpression depending upon the context:

function foo() {}

The above is a FunctionDeclaration.

0, function foo() {}

The above is a FunctionExpression. The difference between the two is explained in fuller detail by @CMS in his aforementioned answer.

In reference to your question:

// A simple function that adds one
var plusOne = function (x) {   // a function expression is assigned to a variable
    return x + 1;
};

function myFunction() {        // a simple function declaration
    return x + 1;
};
Community
  • 1
  • 1
Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
1

in the end. there is no difference between the 2. Just a difference in declaration.

Gabriel McAdams
  • 56,921
  • 12
  • 61
  • 77
  • Sometimes there is a slight difference. Some runtimes will show the first example (the function expression) as merely `anonymous function` in the call stack, where as the second one will have its name listed. This isn't as true as it used to be (Chrome and Firebug are able to figure out reasonable names for function expressions), but still worth pointing out. – Matt Greer Nov 13 '11 at 09:23
  • 1
    There is a significant difference: function statements (the second syntax) are "hoisted" and can thus be called from anywhere on the page (including before the point where the function statement appears). With the "var" syntax the variable declaration is hoisted but the assignment is not, so the function can only be called after that line is executed. – nnnnnn Nov 13 '11 at 09:52
1

They do almost the same thing, but there are differences and reasons for having both. The first a function expression because it is assigned to a variable. In addition, unrelated to being a function expression, it is an anonymous function because it does not have a function name. The second one is a function declaration because it is not part of another expression, and is "a source element (non-nested statement in the script or a body function) of a function of the script." (I don't quite know how to explain a source element so I copied that from Mozilla docs). It also has a function name, myFunction. In addition, the function can also be used before the function declaration, unlike functions defined by a function expression.

The following example using a function expression will not work:

plusOne(1);
var plusOne = function (x) {
    return x + 1;
};

The following using a function declaration instead, will work:

plusOne(1);
function plusOne(x) {
    return x + 1;
};

In addition, seeing as the topic of the link where you saw this function declaration is closures, I'll continue on to explain why you may use a function expression and an anonymous function. Sometimes, a function simply doesn't need a name and can just be anonymous because no one will need to call it by its name. A function expression can be used for something you might have learned about yet, called closures. A closure is when a function encloses variables for use within it at a later time, preventing any outer scope from reaching it. They are a bit difficult to explain, and can also be tough to understand without going through various examples a few times and trying it yourself.

Assuming you have enough basic javascript knowledge (for loops, creating and appending dom elements, and onclick), take for example the following code, which is similar to a problem I encountered before I discovered closures myself. Read through it without running the code first, and try to figure out what will happen when you click each button/div.

function addButtons() {
    for (var i=0; i<3; i++) {
        button = document.createElement("div");
        button.innerHTML = "Button " + i;
        button.onclick = function () {
            alert(i);
        };
        document.body.appendChild(button);
    }
}
addButtons();

You might expect Button 1 to alert "1", and Button 2 to alert "2", and Button 3 to alert "3". However, what happens is all the buttons will alert "3". This is because onclick isn't executed until the variable i has already incremented to 3.

Now read through the next bit of code. It may look a little confusing at first.

function addButtons() {
    for (var i=0; i<3; i++) {
        var button = document.createElement("div");
        button.innerHTML = "Button " + i;
        button.onclick = function (j) {
            return function () {
                alert(j);
            }
        }(i);
        document.body.appendChild(button);
    }
}
addButtons();

If you run it, you will see that each button is alerting what you probably expected them to happe in the first place. Button 1 will alert "1", Button 2 will alert "2", and Button 3 will alert "3". So here, onlick is returning the closure that references j, which set with i during the for loop. The variable j is safely kept in the closure, unlike i, which is changing in each loop. And of course, you can still name the functions used in the closure if you'd like, but there is no reason to.

I'm not sure I explained that perfectly, but I hope it's at least an introduction to something new and useful! There is also a whole lot more information you can find about functions yourself at the Mozilla Developer Network.

andrewh
  • 465
  • 2
  • 10
  • 1
    In your onclick examples both are closures. Closures close on the variable itself, not the value. The first closures closed on i. In the second example you have three different functions closing on three different j's, which is why they are "safe" – Matt Greer Nov 13 '11 at 09:27
  • You're right, thanks for the additional clarification. =) I did say it was tough to explain (at least for me) and might not have been a perfect explanation. – andrewh Nov 13 '11 at 09:31
  • I agree closures are tough to explain. Your post was awesome though. Well thought out and written. – Matt Greer Nov 13 '11 at 09:35
  • _"The first is a function expression because it is assigned to a variable."_ - to be clear, the assignment isn't what makes it an expression, the fact that it appears where an expression is expected is what makes it a function expression, and not all function expressions are assigned to a variable. _"In addition, unrelated to being a function expression, it is an anonymous function because it does not have a function name"_ - It's not completely unrelated: you can't have an anonymous function that isn't a function expression... – nnnnnn Nov 13 '11 at 10:22
0
var plusOne = function (x) {
    return x + 1;
};

is a variable statement whose initializer is a function expression, whereas

function plusTwo(x) {
    return x + 2;
}

is a function declaration.

To understand the difference between the two, you need to understand how variables are initialized:

First, JavaScript variables have function scope (which is a difference to most other popular programming languages, where variables are block-scoped), and variable declaration happens before code evaluation.

This means it doesn't matter where the variable statement is located within the function's body: conceptually, it's the same as if it there were a declaration located right at the top.

However, variables will be pre-initialized to undefined, and the actual value will only be assigned when the variable statement is encountered during code execution.

This is not true for function declarations: Function declarations are evaluated at declaration binding time, ie before general code execution.

In particular, this means that calling a declared function in a statement preceding the declaration is perfectly valid, ie this will work fine:

alert(plusTwo(42));
function plusTwo(x) {
    return x + 2;
};

whereas

alert(plusOne(42));
var plusOne = function (x) {
    return x + 1;
};

will fail as it's conceptually equivalent to

var plusOne = undefined;
alert(plusOne(42));
plusOne = function (x) {
    return x + 1;
};
Christoph
  • 164,997
  • 36
  • 182
  • 240