By Richard Garside


2008-12-03 11:31:07 8 Comments

I've recently started maintaining someone else's JavaScript code. I'm fixing bugs, adding features and also trying to tidy up the code and make it more consistent.

The previous developer uses two ways of declaring functions and I can't work out if there is a reason behind it or not.

The two ways are:

var functionOne = function() {
    // Some code
};
function functionTwo() {
    // Some code
}

What are the reasons for using these two different methods and what are the pros and cons of each? Is there anything that can be done with one method that can't be done with the other?

30 comments

@Jack Giffin 2018-01-15 01:55:57

๐—ง๐—ต๐—ฒ๐—ฟ๐—ฒ ๐—ฎ๐—ฟ๐—ฒ ๐—ณ๐—ผ๐˜‚๐—ฟ ๐—ป๐—ผ๐˜๐—ฒ๐˜„๐—ผ๐—ฟ๐˜๐—ต๐˜† ๐—ฐ๐—ผ๐—บ๐—ฝ๐—ฎ๐—ฟ๐—ถ๐˜€๐—ผ๐—ป๐˜€ ๐—ฏ๐—ฒ๐˜๐˜„๐—ฒ๐—ฒ๐—ป ๐˜๐—ต๐—ฒ ๐˜๐˜„๐—ผ ๐—ฑ๐—ถ๐—ณ๐—ณ๐—ฒ๐—ฟ๐—ฒ๐—ป๐˜ ๐—ฑ๐—ฒ๐—ฐ๐—น๐—ฎ๐—ฟ๐—ฎ๐˜๐—ถ๐—ผ๐—ป๐˜€ ๐—ผ๐—ณ ๐—ณ๐˜‚๐—ป๐—ฐ๐˜๐—ถ๐—ผ๐—ป๐˜€ ๐—ฎ๐˜€ ๐—น๐—ถ๐˜€๐˜๐—ฒ๐—ฑ ๐—ฏ๐—ฒ๐—น๐—ผ๐˜„.

  1. Availability (scope) of the function

The following works because function add() is scoped to the nearest block:

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

function add(a, b){
  return a + b;
}

The following does not work because the variable is called before a function value is assigned to the variable add.

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

var add=function(a, b){
  return a + b;
}

The above code is identical in functionality to the code below. Note that explicitly assigning add = undefined is superfluous because simply doing var add; is the exact same as var add=undefined.

var add = undefined;

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

add = function(a, b){
  return a + b;
}

The following does not work because the var add= superseeds the function add().

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

var add=function add(a, b){
  return a + b;
}

  1. (function).name

The name of a function function thefuncname(){} is thefuncname when it is declared this way.

function foobar(a, b){}

console.log(foobar.name);

var a = function foobar(){};

console.log(a.name);

Otherwise, if a function is declared as function(){}, the function.name is the first variable used to store the function.

var a = function(){};
var b = (function(){ return function(){} });

console.log(a.name);
console.log(b.name);

If there are no variables set to the function, then the functions name is the empty string ("").

console.log((function(){}).name === "");

Lastly, while the variable the function is assigned to initially sets the name, successive variables set to the function do not change the name.

var a = function(){};
var b = a;
var c = b;

console.log(a.name);
console.log(b.name);
console.log(c.name);

  1. Performance

In Google's V8 and Firefox's Spidermonkey there might be a few microsecond JIST compilation difference, but ultimately the result is the exact same. To prove this, let's examine the efficiency of JSPerf at microbenchmarks by comparing the speed of two blank code snippets. The JSPerf tests are found here. And, the jsben.ch testsare found here. As you can see, there is a noticable difference when there should be none. If you are really a performance freak like me, then it might be more worth your while trying to reduce the number of variables and functions in the scope and especially eliminating polymorphism (such as using the same variable to store two different types).

  1. Variable Mutability

When you use the var keyword to declare a variable, you can then reassign a different value to the variable like so.

(function(){
    "use strict";
    var foobar = function(){}; // initial value
    try {
        foobar = "Hello World!"; // new value
        console.log("[no error]");
    } catch(error) {
        console.log("ERROR: " + error.message);
    }
    console.log(foobar, window.foobar);
})();

However, when we use the const-statement, the variable reference becomes immutable. This means that we cannot assign a new value to the variable. Please note, however, that this does not make the contents of the variable immutable: if you do const arr = [], then you can still do arr[10] = "example". Only doing something like arr = "new value" or arr = [] would throw an error as seen below.

(function(){
    "use strict";
    const foobar = function(){}; // initial value
    try {
        foobar = "Hello World!"; // new value
        console.log("[no error]");
    } catch(error) {
        console.log("ERROR: " + error.message);
    }
    console.log(foobar, window.foobar);
})();

Interestingly, if we declare the variable as function funcName(){}, then the immutability of the variable is the same as declaring it with var.

(function(){
    "use strict";
    function foobar(){}; // initial value
    try {
        foobar = "Hello World!"; // new value
        console.log("[no error]");
    } catch(error) {
        console.log("ERROR: " + error.message);
    }
    console.log(foobar, window.foobar);
})();

๐—ช๐—ต๐—ฎ๐˜ ๐—œ๐˜€ ๐—ง๐—ต๐—ฒ "๐—ก๐—ฒ๐—ฎ๐—ฟ๐—ฒ๐˜€๐˜ ๐—•๐—น๐—ผ๐—ฐ๐—ธ"

The "nearest block" is the nearest "function," (including asynchronous functions, generator functions, and asynchronous generator functions). However, interestingly, a function functionName() {} behaves like a var functionName = function() {} when in a non-closure block to items outside said closure. Observe.

  • Normal var add=function(){}

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}');
  }
} catch(e) {
  console.log("Is a block");
}
var add=function(a, b){return a + b}

  • Normal function add(){}

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
function add(a, b){
  return a + b;
}

  • Function

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(function () {
    function add(a, b){
      return a + b;
    }
})();

  • Statement (such as if, else, for, while, try/catch/finally, switch, do/while, with)

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
{
    function add(a, b){
      return a + b;
    }
}

  • Arrow Function with var add=function()

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(() => {
    var add=function(a, b){
      return a + b;
    }
})();

  • Arrow Function With function add()

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(() => {
    function add(a, b){
      return a + b;
    }
})();

@Willem van der Veen 2019-06-20 10:06:36

Difference function declaration and function expression:

Javascript has first class functions. This means that they can be treated just like any other variable. Functions can be passed as arguments in a function, be returned from a function, and can be stored in variables.

However storing function in a variable (function expression) isn't the only way to create a function, this can also be done via a function declaration. Here are the key differences:

  1. Function expressions can be anonymous whereas a function declaration must have a name.
  2. Both have a name property which is used to identify the function. A function expression's name property is the name of the variable which it is bound to, whereas the name of a function declaration is simply the given name.
  3. Function declarations are hoisted whereas, function expressions are not. Only the variable is hoisted to have the value of undefined.

Here is an example:

try {
  functionOne();
} catch (e) {
  console.log('i cant run because im not hoisted');
}

functionTwo();

// function expression, does not get hoisted
let functionOne = function randomName() {
    // Some code
};

// function declaration, gets hoisted
function functionTwo() {
   console.log('I get hoisted');
}

try {
  randomName(); // this isn't the proper name, it is functionOne
} catch (e) {
  console.log('You cant call me with randomName my name is function one');
}

:

@Nitesh Ranjan 2018-10-18 18:57:07

One important point to note is :-

let there are two functions :-

sum(1,2);

const sum = function(first, second) {
  return first + second;
}

In above case, it will give error that sum is not defined, but

sum(1,2);

function sum(first, second) {
  return first + second;
}

This function will not any error as Hoisting will take place in this case.

@Shakespear 2018-12-17 16:58:55

The first one is an Anonymous Function Expression, while the second one is a Function Declaration. Anonymous functions simply have no name. The main difference between an anonymous function expression and a function statement is the function name.

Named Functions Vs. Anonymous Functions

The anonymous function is quick and easy to type, and many libraries and tools tend to encourage this idiomatic style of code. However, anonymous functions have some drawbacks:

  • Readability: anonymous functions omit a name which could cause less readable code.

  • Debugging: anonymous functions have no useful name in stack traces, which can make debugging more difficult.

  • Self-Reference: what if the function needs to refer to itself, for recursion for example.

Naming Function Expression:

Providing a name for your function expression quite effectively addresses all these drawbacks, and has no tangible downsides. The best practice is to always name your function expressions:

setTimeout(function timeHandler() { // <-- look, a name here!
  console.log("I've waited 1 second");
}, 1000);

Naming IIFEs (Immediate Invoked Function Expression):

(function IIFE(str) { // <-- look, always name IIFEs!
  console.log(str); // "Hello!"
})('Hello!');

For functions assigned to a variable, naming the function, in this case, is not very common and may cause confusion, in this case, the arrow function may be a better choice.

@underthecode 2019-02-01 09:20:08

The hoisting behavior between function declarations and expressions is important, but there is another difference between the two:

functions within conditional statements

A general practice recommended by the MDN is to use function expressions instead of declarations inside if statements. From the example in the link, function declarations inside if statements will behave the same across Chrome and Firefox but not on Safari.

Disclaimer: macOS can't run Microsoft Edge, so I can't validate.

// function declaration example

var hoisted = "foo" in this;

console.log(`'foo' name ${hoisted ? "is" : "is not"} hoisted. typeof foo is ${typeof foo}`);

if (false) {
  function foo() {
    return 1;
  }
}

// In Chrome: 
// 'foo' name is hoisted. typeof foo is undefined

// In Firefox:
// 'foo' name is hoisted. typeof foo is undefined

// In Safari:
// 'foo' name is hoisted. typeof foo is function

Transforming foo into a function expression will yield consistent results across all three web browsers.

// function expression example

var hoisted = "foo" in this;

console.log(`'foo' name ${hoisted ? "is" : "is not"} hoisted. typeof foo is ${typeof foo}`);

if (false) {
  var foo = function() {
    return 1;
  }
}

// In Chrome: 
// 'foo' name is hoisted. typeof foo is undefined

// In Firefox:
// 'foo' name is hoisted. typeof foo is undefined

// In Safari:
// 'foo' name is hoisted. typeof foo is undefined

@nullptr 2019-03-17 12:55:05

Look at the Browser Compatibility Table for details

@T.J. Crowder 2014-03-04 13:35:48

Here's the rundown on the standard forms that create functions: (Originally written for another question, but adapted after being moved into the canonical question.)

Terms:

The quick list:

  • Function Declaration

  • "Anonymous" function Expression (which despite the term, sometimes create functions with names)

  • Named function Expression

  • Accessor Function Initializer (ES5+)

  • Arrow Function Expression (ES2015+) (which, like anonymous function expressions, don't involve an explicit name, and yet can create functions with names)

  • Method Declaration in Object Initializer (ES2015+)

  • Constructor and Method Declarations in class (ES2015+)

Function Declaration

The first form is a function declaration, which looks like this:

function x() {
    console.log('x');
}

A function declaration is a declaration; it's not a statement or expression. As such, you don't follow it with a ; (although doing so is harmless).

A function declaration is processed when execution enters the context in which it appears, before any step-by-step code is executed. The function it creates is given a proper name (x in the example above), and that name is put in the scope in which the declaration appears.

Because it's processed before any step-by-step code in the same context, you can do things like this:

x(); // Works even though it's above the declaration
function x() {
    console.log('x');
}

Until ES2015, the spec didn't cover what a JavaScript engine should do if you put a function declaration inside a control structure like try, if, switch, while, etc., like this:

if (someCondition) {
    function foo() {    // <===== HERE THERE
    }                   // <===== BE DRAGONS
}

And since they're processed before step-by-step code is run, it's tricky to know what to do when they're in a control structure.

Although doing this wasn't specified until ES2015, it was an allowable extension to support function declarations in blocks. Unfortunately (and inevitably), different engines did different things.

As of ES2015, the specification says what to do. In fact, it gives three separate things to do:

  1. If in loose mode not on a web browser, the JavaScript engine is supposed to do one thing
  2. If in loose mode on a web browser, the JavaScript engine is supposed to do something else
  3. If in strict mode (browser or not), the JavaScript engine is supposed to do yet another thing

The rules for the loose modes are tricky, but in strict mode, function declarations in blocks are easy: They're local to the block (they have block scope, which is also new in ES2015), and they're hoisted to the top of the block. So:

"use strict";
if (someCondition) {
    foo();               // Works just fine
    function foo() {
    }
}
console.log(typeof foo); // "undefined" (`foo` is not in scope here
                         // because it's not in the same block)

"Anonymous" function Expression

The second common form is called an anonymous function expression:

var y = function () {
    console.log('y');
};

Like all expressions, it's evaluated when it's reached in the step-by-step execution of the code.

In ES5, the function this creates has no name (it's anonymous). In ES2015, the function is assigned a name if possible by inferring it from context. In the example above, the name would be y. Something similar is done when the function is the value of a property initializer. (For details on when this happens and the rules, search for SetFunctionName in the the specification — it appears all over the place.)

Named function Expression

The third form is a named function expression ("NFE"):

var z = function w() {
    console.log('zw')
};

The function this creates has a proper name (w in this case). Like all expressions, this is evaluated when it's reached in the step-by-step execution of the code. The name of the function is not added to the scope in which the expression appears; the name is in scope within the function itself:

var z = function w() {
    console.log(typeof w); // "function"
};
console.log(typeof w);     // "undefined"

Note that NFEs have frequently been a source of bugs for JavaScript implementations. IE8 and earlier, for instance, handle NFEs completely incorrectly, creating two different functions at two different times. Early versions of Safari had issues as well. The good news is that current versions of browsers (IE9 and up, current Safari) don't have those issues any more. (But as of this writing, sadly, IE8 remains in widespread use, and so using NFEs with code for the web in general is still problematic.)

Accessor Function Initializer (ES5+)

Sometimes functions can sneak in largely unnoticed; that's the case with accessor functions. Here's an example:

var obj = {
    value: 0,
    get f() {
        return this.value;
    },
    set f(v) {
        this.value = v;
    }
};
console.log(obj.f);         // 0
console.log(typeof obj.f);  // "number"

Note that when I used the function, I didn't use ()! That's because it's an accessor function for a property. We get and set the property in the normal way, but behind the scenes, the function is called.

You can also create accessor functions with Object.defineProperty, Object.defineProperties, and the lesser-known second argument to Object.create.

Arrow Function Expression (ES2015+)

ES2015 brings us the arrow function. Here's one example:

var a = [1, 2, 3];
var b = a.map(n => n * 2);
console.log(b.join(", ")); // 2, 4, 6

See that n => n * 2 thing hiding in the map() call? That's a function.

A couple of things about arrow functions:

  1. They don't have their own this. Instead, they close over the this of the context where they're defined. (They also close over arguments and, where relevant, super.) This means that the this within them is the same as the this where they're created, and cannot be changed.

  2. As you'll have noticed with the above, you don't use the keyword function; instead, you use =>.

The n => n * 2 example above is one form of them. If you have multiple arguments to pass the function, you use parens:

var a = [1, 2, 3];
var b = a.map((n, i) => n * i);
console.log(b.join(", ")); // 0, 2, 6

(Remember that Array#map passes the entry as the first argument, and the index as the second.)

In both cases, the body of the function is just an expression; the function's return value will automatically be the result of that expression (you don't use an explicit return).

If you're doing more than just a single expression, use {} and an explicit return (if you need to return a value), as normal:

var a = [
  {first: "Joe", last: "Bloggs"},
  {first: "Albert", last: "Bloggs"},
  {first: "Mary", last: "Albright"}
];
a = a.sort((a, b) => {
  var rv = a.last.localeCompare(b.last);
  if (rv === 0) {
    rv = a.first.localeCompare(b.first);
  }
  return rv;
});
console.log(JSON.stringify(a));

The version without { ... } is called an arrow function with an expression body or concise body. (Also: A concise arrow function.) The one with { ... } defining the body is an arrow function with a function body. (Also: A verbose arrow function.)

Method Declaration in Object Initializer (ES2015+)

ES2015 allows a shorter form of declaring a property that references a function called a method definition; it looks like this:

var o = {
    foo() {
    }
};

the almost-equivalent in ES5 and earlier would be:

var o = {
    foo: function foo() {
    }
};

the difference (other than verbosity) is that a method can use super, but a function cannot. So for instance, if you had an object that defined (say) valueOf using method syntax, it could use super.valueOf() to get the value Object.prototype.valueOf would have returned (before presumably doing something else with it), whereas the ES5 version would have to do Object.prototype.valueOf.call(this) instead.

That also means that the method has a reference to the object it was defined on, so if that object is temporary (for instance, you're passing it into Object.assign as one of the source objects), method syntax could mean that the object is retained in memory when otherwise it could have been garbage collected (if the JavaScript engine doesn't detect that situation and handle it if none of the methods uses super).

Constructor and Method Declarations in class (ES2015+)

ES2015 brings us class syntax, including declared constructors and methods:

class Person {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    getFullName() {
        return this.firstName + " " + this.lastName;
    }
}

There are two function declarations above: One for the constructor, which gets the name Person, and one for getFullName, which is a function assigned to Person.prototype.

@BiAiB 2014-03-04 13:37:32

then the name w is simply ignored ?

@LGSon 2014-03-04 13:39:51

is it meant for the purpose documentation/code comment, where the name give's a hint of what the function do?

@T.J. Crowder 2014-03-04 13:42:12

@BiAiB: Not quite. It's not added to the scope the expression is in, but it is in scope within the function.

@T.J. Crowder 2014-03-04 13:42:57

@PellePenna: Function names are useful for lots of things. The two biggies in my view are recursion, and the name of the function being shown in call stacks, exception traces, and such.

@ScrapCode 2016-02-10 10:19:34

@ChaimEliyah - "Accepting doesn't mean it's the best answer, it just means that it worked for the person who asked." source

@T.J. Crowder 2016-02-10 10:32:23

@A.R.: Quite true. Amusingly, though, right above that it says "The best answers show up first so that they are always easy to find." Since the accepted answer shows up first even over higher-voted answers, the tour might be somewhat self-contradicting. ;-) Also a bit inaccurate, if we determine "best" by votes (which isn't reliable, it's just what we've got), "best" answers only show up first if you're using the "Votes" tab -- otherwise, the answers that are first are the active ones, or the oldest ones.

@ScrapCode 2016-02-10 10:46:56

@T.J.Crowder : Agreed. 'arranged by date' is sometimes annoying.

@Ynot 2018-04-23 20:37:22

@T.J.Crowder, ESLint agrees with you.

@ealef 2019-01-11 13:41:28

Is there an advantage by using the ES6 Method Declaration in Object Initializer over the ES5?

@T.J. Crowder 2019-01-11 14:01:41

@ealef - Other than being more concise, the only other advantage is if you need to use super within the function to access Object's version of something. (I've updated the answer to clarify that.)

@H.Ostwal 2019-01-02 06:50:44

Another difference between both function is functionOne can be used as a variable that can hold multiple functions within and functionTwo holds some block of code that gets executed all when called. Please check below :

   var functionOne = (function() {
      return {

         sayHello: function(){
                console.log('say hello')

         },
         redirectPage:function(_url){
                window.location.href = _url;
         }

      }
})();

You have a choice which function to be called. e.g functionOne.sayHello or functionOne. redirectPage. And if you call functionTwo then whole block of code will get executed.

@Kean Amaral 2018-07-14 22:56:13

This is called a Function Expression:

var getRectArea = function(width, height) {
    return width * height;
};

console.log("Area of Rectangle: " + getRectArea(3,4));
// This should return the following result in the console: 
// Area of Rectangle: 12

This is called a Function Declaration:

var w = 5;
var h = 6;

function RectArea(width, height) {  //declaring the function
  return area = width * height;
}                                   //note you do not need ; after }

RectArea(w,h);                      //calling or executing the function
console.log("Area of Rectangle: " + area);
// This should return the following result in the console: 
// Area of Rectangle: 30

Hope this helps explain what is the difference between Function Expression and Function Declaration and how to use them. Thanks.

@Adi Darachi 2018-11-20 13:47:44

What am I looking at? I don't think this explains the question, nither that you do understand what you did, In the second example, the only reason you can access the 'area' variable is that you did not declare it, so it registered on window.area instead.

@Greg 2008-12-03 11:37:42

The difference is that functionOne is a function expression and so only defined when that line is reached, whereas functionTwo is a function declaration and is defined as soon as its surrounding function or script is executed (due to hoisting).

For example, a function expression:

// TypeError: functionOne is not a function
functionOne();

var functionOne = function() {
  console.log("Hello!");
};

And, a function declaration:

// Outputs: "Hello!"
functionTwo();

function functionTwo() {
  console.log("Hello!");
}

This also means you can't conditionally define functions using function declarations:

if (test) {
   // Error or misbehavior
   function functionThree() { doSomething(); }
}

The above actually defines functionThree irrespective of test's value — unless use strict is in effect, in which case it simply raises an error.

@ma11hew28 2011-01-13 20:48:43

I tested your first point (compile-time vs. run-time) in Firefox & Google Chrome, and it seems valid. But your second point about scope seems flawed: functionTwo is scoped too.

@Mörre 2011-03-18 11:32:02

@Gio Borje: In exactly the same way. It's Javascript. Why do you think it would make a difference WHERE it runs?

@Jesse Hallett 2011-07-21 01:06:17

@MattDiPasquale Because of the "var" declaration the variable "functionTwo" is in scope on the line where it is invoked. But the that variable is not assigned a value until the next line. So when "functionTwo" is invoked its value is still undefined. Trying to invoke undefined as a function results in an error.

@Jason Bunting 2011-08-05 21:18:09

@Greg: By the way, the difference isn't only that they are parsed at different times. Essentially, your functionOne is merely a variable that has an anonymous function assigned to it, whereas functionTwo is actually a named function. Call .toString() on both to see the difference. This is significant in some cases where you want to get the name of a function programmatically.

@Jon z 2011-09-09 16:29:42

@Jason Bunting.. not sure what you're getting at here, .toString() seems to return essentially the same value (the function definition) for both: cl.ly/2a2C2Y1r0J451o0q0B1B

@Tim Down 2011-09-22 10:39:26

@Jon z: functionTwo has a name. It shows up in string represenations of the function, in the non-standard name property of the function (developer.mozilla.org/en/JavaScript/Reference/Global_Object‌​s/…) and in stack traces and debuggers. It is a useful thing.

@Michal Kuklis 2011-11-14 06:03:31

There are both different. The first one is a function expression the second one is a function declaration. You can read more on the topic here: javascriptweblog.wordpress.com/2010/07/06/…

@ล ime Vidas 2012-01-04 00:59:56

@Greg The part of your answer concerning parse time vs. run time is not correct. In JavaScript, function declarations are not defined during parse time, but during run time. The process goes like this: Source code is parsed -> JavaScript program is evaluated -> The global execution context is initialized -> declaration binding instantiation is performed. During this process the function declarations are instantiated (see step 5 of Chapter 10.5).

@gtd 2012-04-28 16:13:47

Note also that you can do both! However the named function name will only be available inside the function. See ejohn.org/apps/learn/#14

@Milimetric 2012-06-24 14:08:57

what about memory usage? Can't the var functionName = function style be garbage collected earlier in some circumstances?

@Nathan MacInnes 2012-12-21 12:34:41

All the example proves is that the function is that functionOne is given a name on creation of the scope, whereas functionTwo isn't given a name until the assignment happens. Yes, that is significant, but it doesn't prove anything about parse-time vs run-time.

@Colin Pear 2013-01-03 07:22:33

The terminology for this phenomenon is known as hoisting.

@1nfiniti 2013-05-05 15:22:22

The named vs unnamed aspect to this question is also important for profiling/debugging your code. Anonymous functions are inherently difficult to profile, because you get limited feedback as to what function is using up memory. Assigning an anonymous function to a variable does not name the function. There is no rule preventing you from also naming a function expression i.e. -> var x = function myFunctionsName(){...}; However, I do not know when a function expression pointing to a named function (instead of an anonymous one) gets defined (parse-time vs run-time).

@1nfiniti 2013-05-05 15:30:55

Looks like a named function expression is still executed @ parse-time (even if it's called by the function name instead of the variable name).

@Richard Garside 2013-08-11 09:39:15

@san.chez Eugene's answer is more in depth, but without Greg's answer it doesn't make sense.

@Eric 2013-08-23 13:31:13

Is there any advantage to using var function then?

@natlee75 2013-10-08 16:24:01

@user1803405 I have never encountered a scenario where it was beneficial to use an assignment of a function definition to a variable declaration instead of a plain old vanilla function declaration. The function declaration accomplishes everything that the variable declaration technique does with the added benefit of hoisting and naming (for internal reference of a function to itself as well as easier debugging). Some of the developers at my current company like the variable declaration as an enforcement of declaring before using, but I constantly argue against it since it offers no real value.

@Nelu 2013-12-13 15:56:26

Is "parse time" the same thing as "compile time"?

@Eat at Joes 2014-05-14 16:01:53

I think it is more important to know the scope of theses two; the function -> functionTwo and the function expression -> functionOne. The function declaration is available before any code is executed, therefore functionTwo is accessible throughout it's closure. While the function expression is accessible only when the interpreter reaches that line.

@Hart Simha 2014-06-12 06:16:48

The edit from April 30th (the final script example in the code block) is a little bereft of detail. From the edit comment it looks like it's intended to illustrate that you can't declare a function within a block in strict mode. If my interpretation is correct, perhaps someone could clarify that?

@Casey Dwayne 2014-09-09 15:48:04

Interesting. According to this test, the same function declared at parse-time was 87% slower, run-time yielding exponentially more OPS.

@Javascript Coder 2015-02-10 07:34:06

@JasonBunting I have assinged toString but i am not gtting any difference.. for both I am geting : TypeError: Cannot read property 'toString' of undefined

@tsubik 2015-05-03 19:29:51

it is all about hoisting not some parse or run-time stuff. definition of functionTwo is hoisted on top of script block, only declaration of functionOne variable is hoisted to the top of block, definition stays where it was, so functionOne is undefined before assigning.

@RobG 2015-10-16 15:07:01

@Jason Buntingโ€”they aren't "parsed at different times" (that is an impossibility since they must be parsed to be recognised), they are processed at different times. Function declarations are processed before any code is executed, function expressions are processed when execution reaches them.

@Jason Bunting 2015-11-10 20:12:45

@RobG - I understand the difference, it was sloppily written 4 years ago. Too bad I can't edit the text of that comment...

@Michael Rasoahaingo 2016-06-02 00:01:30

Another difference is that the first is an anonymous function that is difficult to IDENTIFY in the stack trace ERROR, instead the the second that is given a name

@Santosh Pillai 2018-05-15 00:22:23

Expression in JS: Something that returns a value
Example: Try out following in chrome console:

a = 10
output : 10

(1 + 3)
output = 4

Declaration/Statement: Something that does not return a value
Example:

if (1 > 2) {
 // do something. 
}

here (1>2) is an expression but the 'if' statament is not. Its not returning anything.


Similarly, we have Function Declaration/Statement vs Function Expression
Lets take an example:

// test.js

var a = 10;

// function expression
var fun_expression = function() {
   console.log("Running function Expression");
}

// funciton expression

function fun_declaration() {
   console.log("Running function Statement");
}

Important: What happens when JavaScript engines runs the above js file.

  • When this js runs following things will happen:

    1. Memory will be created variable 'a' and 'fun_expression'. And memory will be created for function statement 'fun_declaration'
    2. 'a' will be assigned 'undefined'. 'fun_expression' will be assigned 'undefined'. 'fun_declaration' will be in the memory in its entirety.
      Note: Step 1 and 2 above are called 'Execution Context - Creation Phase'.

Now suppose we update the js to.

// test.js

console.log(a)  //output: udefined (No error)
console.log(fun_expression)  // output: undefined (No error)
console.log(fun_expression()) // output: Error. As we trying to invoke undefined. 
console.log(fun_declaration()) // output: running function statement  (As fun_declaration is already hoisted in the memory). 

var a = 10;

// function expression
var fun_expression = function() {
   console.log('Running function expression')
}

// function declaration

function fun_declaration() {
   console.log('running function declaration')
}

console.log(a)   // output: 10
console.log(fun_expression()) //output: Running function expression
console.log(fun_declaration()) //output: running function declaration

The output mentioned above in the comments, should be useful to understand the different between function expression and function statement/declaration.

@user2693928 2018-03-08 11:49:32

I prefer defining function as variable:

let first = function(x){
   return x[0];
}

Instead of:

function first(){
    ....
}

Because i can use expressions and decorators when defining the function. For example:

let safe = function(f){
  try {f()...}
}
let last = safe(function(x){return x[0]}).

Also with ES6 its much shorter:

 let last = x => x[0]
 ...........
 function last(x){
     return x[0];
 }
......

let last = safe(x => x[0]);

@Jack Giffin 2018-06-18 17:35:22

I fail to see how this style of coding offers the least bit of performance.

@Yash 2016-01-25 14:46:53

Hoisting is the JavaScript interpreterโ€™s action of moving all variable and function declarations to the top of the current scope.

However, only the actual declarations are hoisted. by leaving assignments where they are.

  • variable's/Function's declared inside the page are global can access anywhere in that page.
  • variable's/Functions declared inside the function are having local scope. means they are available/accessed inside the function body (scope), they are not available outside the function body.

Variable

Javascript is called loosely typed language. Which means Javascript variables can hold value of any Data-Type. Javascript automatically takes care of changing the variable-type based on the value/literal provided during runtime.

global_Page = 10;                                               var global_Page;      ยซ undefined
    ยซ Integer literal, Number Type.   -------------------       global_Page = 10;     ยซ Number         
global_Page = 'Yash';                 |   Interpreted   |       global_Page = 'Yash'; ยซ String
    ยซ String literal, String Type.    ยซ       AS        ยซ       global_Page = true;   ยซ Boolean 
var global_Page = true;               |                 |       global_Page = function (){          ยซ function
    ยซ Boolean Type                    -------------------                 var local_functionblock;  ยซ undefined
global_Page = function (){                                                local_functionblock = 777;ยซ Number
    var local_functionblock = 777;                              };  
    // Assigning function as a data.
};  

Function

function Identifier_opt ( FormalParameterList_opt ) { 
      FunctionBody | sequence of statements

      ยซ return;  Default undefined
      ยซ return 'some data';
}
  • functions declared inside the page are hoisted to top of the page having global access.
  • functions declared inside the function-block are hoisted to top of the block.
  • Default return value of function is 'undefined', Variable declaration default value also 'undefined'

    Scope with respect to function-block global. 
    Scope with respect to page undefined | not available.
    

Function Declaration

function globalAccess() {                                  function globalAccess() {      
}                                  -------------------     }
globalAccess();                    |                 |     function globalAccess() { ยซ Re-Defined / overridden.
localAccess();                     ยซ   Hoisted  As   ยซ         function localAccess() {
function globalAccess() {          |                 |         }
     localAccess();                -------------------         localAccess(); ยซ function accessed with in globalAccess() only.
     function localAccess() {                              }
     }                                                     globalAccess();
}                                                          localAccess(); ยซ ReferenceError as the function is not defined

Function Expression

        10;                 ยซ literal
       (10);                ยซ Expression                (10).toString() -> '10'
var a;                      
    a = 10;                 ยซ Expression var              a.toString()  -> '10'
(function invoke() {        ยซ Expression Function
 console.log('Self Invoking');                      (function () {
});                                                               }) () -> 'Self Invoking'

var f; 
    f = function (){        ยซ Expression var Function
    console.log('var Function');                                   f ()  -> 'var Function'
    };

Function assigned to variable Example:

(function selfExecuting(){
    console.log('IIFE - Immediately-Invoked Function Expression');
}());

var anonymous = function (){
    console.log('anonymous function Expression');
};

var namedExpression = function for_InternalUSE(fact){
    if(fact === 1){
        return 1;
    }

    var localExpression = function(){
        console.log('Local to the parent Function Scope');
    };
    globalExpression = function(){ 
        console.log('creates a new global variable, then assigned this function.');
    };

    //return; //undefined.
    return fact * for_InternalUSE( fact - 1);   
};

namedExpression();
globalExpression();

javascript interpreted as

var anonymous;
var namedExpression;
var globalExpression;

anonymous = function (){
    console.log('anonymous function Expression');
};

namedExpression = function for_InternalUSE(fact){
    var localExpression;

    if(fact === 1){
        return 1;
    }
    localExpression = function(){
        console.log('Local to the parent Function Scope');
    };
    globalExpression = function(){ 
        console.log('creates a new global variable, then assigned this function.');
    };

    return fact * for_InternalUSE( fact - 1);    // DEFAULT UNDEFINED.
};

namedExpression(10);
globalExpression();

You can check function declaration, expression test over different browser's using jsperf Test Runner


ES5 Constructor Function Classes: Function objects created using Function.prototype.bind

JavaScript treats functions as first-class objects, so being an object, you can assign properties to a function.

function Shape(id) { // Function Declaration
    this.id = id;
};
    // Adding a prototyped method to a function.
    Shape.prototype.getID = function () {
        return this.id;
    };
    Shape.prototype.setID = function ( id ) {
        this.id = id;
    };

var expFn = Shape; // Function Expression

var funObj = new Shape( ); // Function Object
funObj.hasOwnProperty('prototype'); // false
funObj.setID( 10 );
console.log( funObj.getID() ); // 10

ES6 introduced Arrow function: An arrow function expression has a shorter syntax, they are best suited for non-method functions, and they cannot be used as constructors.

ArrowFunction : ArrowParameters => ConciseBody.

const fn = (item) => { return item & 1 ? 'Odd' : 'Even'; };
console.log( fn(2) ); // Even
console.log( fn(3) ); // Odd

@Danish 2016-01-31 17:56:52

ahm, your answer... isn't it ambiguous? well written though so +1 for spending and writing too much info.

@Panos Kal. 2017-09-28 04:34:23

About performance:

New versions of V8 introduced several under-the-hood optimizations and so did SpiderMonkey.

There is almost no difference now between expression and declaration.
Function expression appears to be faster now.

Chrome 62.0.3202 Chrome test

FireFox 55 Firefox test

Chrome Canary 63.0.3225 Chrome Canary test


Anonymous function expressions appear to have better performance against Named function expression.


Firefox Firefox named_anonymous Chrome Canary Chrome canary named_anonymous Chrome Chrome named_anonymous

@squidbe 2017-11-26 01:41:53

Yes, this difference is so insignificant that hopefully devs will concern themselves with which approach is more maintainable for their specific needs rather than which one might be faster (you'll get different jsperf results on each try depending on what the browser is doing -- the majority of javascript tasks needn't concern themselves with micro-optimizations to this degree).

@Jack Giffin 2018-05-10 21:10:00

@squidbe There is no difference. Look here: jsperf.com/empty-tests-performance

@Alireza 2017-05-09 13:56:36

They are pretty similar with some small differences, first one is a variable which assigned to an anonymous function (Function Declaration) and second one is the normal way to create a function in JavaScript(Anonymous function Declaration), both has usage, cons and pros:

1. Function Expression

var functionOne = function() {
    // Some code
};

A Function Expression defines a function as a part of a larger expression syntax (typically a variable assignment ). Functions defined via Functions Expressions can be named or anonymous. Function Expressions must not start with โ€œfunctionโ€ (hence the parentheses around the self invoking example below).

Assign a variable to a function, means no Hoisting, as we know functions in JavaScript can Hoist, means they can be called before they get declared, while variables need to be declared before getting access to them, so means in this case we can not access the function before where it's declared, also it could be a way that you write your functions, for the functions which return another function, this kind of declaration could make sense, also in ECMA6 & above you can assign this to an arrow function which can be used to call anonymous functions, also this way of declaring is a better way to create Constructor functions in JavaScript.

2. Function Declaration

function functionTwo() {
    // Some code
}

A Function Declaration defines a named function variable without requiring variable assignment. Function Declarations occur as standalone constructs and cannot be nested within non-function blocks. Itโ€™s helpful to think of them as siblings of Variable Declarations. Just as Variable Declarations must start with โ€œvarโ€, Function Declarations must begin with โ€œfunctionโ€.

This is the normal way of calling a function in JavaScript, this function can be called before you even declare it as in JavaScript all functions get Hoisted, but if you have 'use strict' this won't Hoist as expected, it's a good way to call all normal functions which are not big in lines and neither are a constructor function.

Also, if you need more info about how hoisting works in JavaScript, visit the link below:

https://developer.mozilla.org/en-US/docs/Glossary/Hoisting

@Karl Morrison 2017-06-13 12:44:01

...also this way of declaring is a better way to create Constructor functions in JavaScript , may you please elaborate, I'm curious!

@Alireza 2017-06-13 12:56:45

One reason is because all built-in Constructor functions in JavaScript created like this function Number() { [native code] } and you shouldn't be confused with built-in ones, also referencing later on in this case is safer and you end up neater code but not using hoisting...

@Mbengue Assane 2013-03-29 13:26:24

An illustration of when to prefer the first method to the second one is when you need to avoid overriding a function's previous definitions.

With

if (condition){
    function myfunction(){
        // Some code
    }
}

, this definition of myfunction will override any previous definition, since it will be done at parse-time.

While

if (condition){
    var myfunction = function (){
        // Some code
    }
}

does the correct job of defining myfunction only when condition is met.

@Alexander Mills 2015-05-26 20:31:32

this example is good and is close to perfection, but could be improved. the better example would be to defined var myFunc = null; outside of a loop, or outside of an if/elseif/else block. Then you can conditionally assign different functions to the same variable. In JS, it is a better convention to assign a missing value to null, then to undefined. Therefore, you should declare myFunction as null first, then assign it later, conditionally.

@Anoop Rai 2016-08-14 09:13:55

In JavaScript there are two ways to create functions:

  1. Function declaration:

    function fn(){
      console.log("Hello");
    }
    fn();
    

    This is very basic, self-explanatory, used in many languages and standard across C family of languages. We declared a function defined it and executed it by calling it.

    What you should be knowing is that functions are actually objects in JavaScript; internally we have created an object for above function and given it a name called fn or the reference to the object is stored in fn. Functions are objects in JavaScript; an instance of function is actually an object instance.

  2. Function expression:

    var fn=function(){
      console.log("Hello");
    }
    fn();
    

    JavaScript has first-class functions, that is, create a function and assign it to a variable just like you create a string or number and assign it to a variable. Here, the fn variable is assigned to a function. The reason for this concept is functions are objects in JavaScript; fn is pointing to the object instance of the above function. We have initialized a function and assigned it to a variable. It's not executing the function and assigning the result.

Reference: JavaScript function declaration syntax: var fn = function() {} vs function fn() {}

@chharvey 2016-08-20 00:40:27

what about the third option, var fn = function fn() {...}?

@Anoop Rai 2016-08-23 10:00:44

Hi Chharvey, not sure about ur question, I guess u r talking about function expression which I have already mentioned. However, if still there is some confusion just be more elaborative.

@chharvey 2016-08-23 10:39:46

yes I was asking about a named function expression. it's similar to your option #2 except that the function has an identifier. usually this identifier is the same as the variable it's being assigned to, but that's not always the case.

@Anoop Rai 2016-08-23 11:42:19

Yes Named function expression is similar to my option #2. Well having an identifier is not mandatory as it's not used. Whenever you will be executing the function expression you will use the variable holding the function object. Identifier serves no purpose.

@suhailvs 2014-08-09 02:45:38

A better explanation to Greg's answer

functionTwo();
function functionTwo() {
}

Why no error? We were always taught that expressions are executed from top to bottom(??)

Because:

Function declarations and variable declarations are always moved (hoisted) invisibly to the top of their containing scope by the JavaScript interpreter. Function parameters and language-defined names are, obviously, already there. ben cherry

This means that code like this:

functionOne();                  ---------------      var functionOne;
                                | is actually |      functionOne();
var functionOne = function(){   | interpreted |-->
};                              |    like     |      functionOne = function(){
                                ---------------      };

Notice that the assignment portion of the declarations were not hoisted. Only the name is hoisted.

But in the case with function declarations, the entire function body will be hoisted as well:

functionTwo();              ---------------      function functionTwo() {
                            | is actually |      };
function functionTwo() {    | interpreted |-->
}                           |    like     |      functionTwo();
                            ---------------

@Sharathi RB 2016-02-02 12:09:06

HI suhail thanks for clear info about function topic. Now my question is which one will be the first declaration in declaration hierarchy whether variable declaration (functionOne) or function declaration (functionTwo) ?

@Rob 2010-08-08 19:44:40

An important reason is to add one and only one variable as the "Root" of your namespace...

var MyNamespace = {}
MyNamespace.foo= function() {

}

or

var MyNamespace = {
  foo: function() {
  },
  ...
}

There are many techniques for namespacing. It's become more important with the plethora of JavaScript modules available.

Also see How do I declare a namespace in JavaScript?

@Andrew Barber 2013-05-29 21:13:50

It appears this answer was merged into this question from another question, and the wording might seem to be a tiny bit unrelated to this question. Would you consider editing the answer so it seems more directed specifically at this question? (to reiterate; this isn't your fault at all... just a side-effect of a merged question). You can also delete it, and I think you would keep your reputation. Or you can leave it; since it's old, it may not make a big difference.

@Eugene Lazutkin 2008-12-03 17:43:35

First I want to correct Greg: function abc(){} is scoped too — the name abc is defined in the scope where this definition is encountered. Example:

function xyz(){
  function abc(){};
  // abc is defined here...
}
// ...but not here

Secondly, it is possible to combine both styles:

var xyz = function abc(){};

xyz is going to be defined as usual, abc is undefined in all browsers but Internet Explorer — do not rely on it being defined. But it will be defined inside its body:

var xyz = function abc(){
  // xyz is visible here
  // abc is visible here
}
// xyz is visible here
// abc is undefined here

If you want to alias functions on all browsers, use this kind of declaration:

function abc(){};
var xyz = abc;

In this case, both xyz and abc are aliases of the same object:

console.log(xyz === abc); // prints "true"

One compelling reason to use the combined style is the "name" attribute of function objects (not supported by Internet Explorer). Basically when you define a function like

function abc(){};
console.log(abc.name); // prints "abc"

its name is automatically assigned. But when you define it like

var abc = function(){};
console.log(abc.name); // prints ""

its name is empty — we created an anonymous function and assigned it to some variable.

Another good reason to use the combined style is to use a short internal name to refer to itself, while providing a long non-conflicting name for external users:

// Assume really.long.external.scoped is {}
really.long.external.scoped.name = function shortcut(n){
  // Let it call itself recursively:
  shortcut(n - 1);
  // ...
  // Let it pass itself as a callback:
  someFunction(shortcut);
  // ...
}

In the example above we can do the same with an external name, but it'll be too unwieldy (and slower).

(Another way to refer to itself is to use arguments.callee, which is still relatively long, and not supported in the strict mode.)

Deep down, JavaScript treats both statements differently. This is a function declaration:

function abc(){}

abc here is defined everywhere in the current scope:

// We can call it here
abc(); // Works

// Yet, it is defined down there.
function abc(){}

// We can call it again
abc(); // Works

Also, it hoisted through a return statement:

// We can call it here
abc(); // Works
return;
function abc(){}

This is a function expression:

var xyz = function(){};

xyz here is defined from the point of assignment:

// We can't call it here
xyz(); // UNDEFINED!!!

// Now it is defined
xyz = function(){}

// We can call it here
xyz(); // works

Function declaration vs. function expression is the real reason why there is a difference demonstrated by Greg.

Fun fact:

var xyz = function abc(){};
console.log(xyz.name); // Prints "abc"

Personally, I prefer the "function expression" declaration because this way I can control the visibility. When I define the function like

var abc = function(){};

I know that I defined the function locally. When I define the function like

abc = function(){};

I know that I defined it globally providing that I didn't define abc anywhere in the chain of scopes. This style of definition is resilient even when used inside eval(). While the definition

function abc(){};

depends on the context and may leave you guessing where it is actually defined, especially in the case of eval() — the answer is: It depends on the browser.

@Eugene Lazutkin 2009-07-26 02:52:14

I refer to RoBorg but he is nowhere to be found. Simple: RoBorg === Greg. That's how history can be rewritten in the age of internet. ;-)

@NVI 2009-12-03 17:43:04

var xyz = function abc(){}; console.log(xyz === abc); All browsers I've tested (Safari 4, Firefox 3.5.5, Opera 10.10) gives me "Undefined variable: abc".

@natlee75 2013-10-08 16:30:28

Overall I think this post does a good job of explaining the differences and the advantages of utilizing the function declaration. I'll agree to disagree as far as the benefits of utilizing function expression assignments to a variable especially since the "benefit" seems to be an advocation of declaring a global entity... and everyone knows that you shouldn't clutter the global namespace, right? ;-)

@goat 2014-01-26 18:25:18

imo a huge reason to use named function is because debuggers can use the name to help you make sense of your call stack or stack trace. it sucks when you look at the call stack and see "anonymous function" 10 levels deep...

@Antimony 2014-03-24 18:09:00

Function declarations inside blocks are not part of the Ecmascript standard. Your first example is implementation dependent and forbidden according to Google's style guide. source

@Cypher 2014-03-27 23:25:38

@Antimony A function declaration is not the same thing as a block. This should explain better: stackoverflow.com/questions/17409945/…

@Cristian Garcia 2014-05-01 18:45:47

I am considering to always use var abc = function abc() for local and abc = function abc() for global functions.

@jtheletter 2014-06-18 21:55:44

For Mozilla's documentation of this "combined" function definition format, see โ€“ developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

@user2700923 2014-07-02 18:11:41

There's another reason to use a function declaration: Defining a function within a loop.

@JLRishe 2015-01-03 20:19:54

@CristianGarcia I would recommend against using abc = function abc() to define global functions, because (a) It's forbidden in strict mode (unless abc was pre-declared elsewhere, but then you've really got a mess on your hands). (b) You should be minimizing the amount of stuff you add to the global scope as it is. (c) It's downright confusing to anyone trying to figure out where abc is coming from.

@JoshuaDavid 2015-01-12 07:59:29

Along the lines of @goat... with frameworks like angularJS which rely heavily on nested functions, the combined syntax is not just a luxury but downright required for any reasonably efficient debugging experience

@Alexander Mills 2015-07-02 18:59:51

IMO, if you are going to use a global on the front-end, just suck it up, and upon first declaration put window.foo = "".

@programmer5000 2017-01-26 14:19:18

@goat modern debuggers (the devtools in most recent browsers) will show you the identifier of an anonymous function. Paste this in your dev console: var x = function(){ throw new Error("Oh no!"); }; x();

@Harsha 2017-04-02 06:55:45

That's a really detailed answer! I'm a learner and I like to know how to learn a programming language so well.

@Quinn Dirks 2018-03-05 22:32:12

If you try xyz(); in the browser console, and xyz has not been declared via var or function within the current scope, you will get a ReferenceError. If xyz is declared within the current scope through the use of var, but after the xyz(); statement, you will get a TypeError. If xyz is declared in the current scope via function, you may still see undefined logged to the console. This is because browser consoles log the result of operations performed in the console, and we have not defined xyz to have a return value, meaning the return value is implicitly undefined.

@Qwerty 2018-05-04 12:49:49

var abc = function(){}; console.log(abc.name); does not produce "" any more, but "abc" instead.

@dylnmc 2018-05-17 18:43:44

in my firefox quantum, f = function(){}; console.log(f.name) still returns undefined but in chrome, it returns f.

@Dementic 2019-01-10 02:53:58

as per the alias function abc(){}; var xyz = abc; IMHO var xyz = abc = function(){} is a more understandable.

@SuperNova 2016-05-10 07:05:46

new Function() can be used to pass the function's body in a string. And hence this can be used to create dynamic functions. Also passing the script without executing the script.

var func = new Function("x", "y", "return x*y;");
function secondFunction(){
   var result;
   result = func(10,20);
   console.log ( result );
}

secondFunction()

@Jack Giffin 2018-05-10 21:06:04

While this is good and true, how exactly does this alone relate to the quesiton being asked?

@Nitin9791 2015-12-28 20:18:03

Both are different ways of defining a function. The difference is how the browser interprets and loads them into an execution context.

The first case is of function expressions which loads only when the interpreter reaches that line of code. So if you do it like the following, you will get an error that the functionOne is not a function.

functionOne();
var functionOne = function() {
    // Some code
};

The reason is that on the first line no value is assigned to functionOne, and hence it is undefined. We are trying to call it as a function, and hence we are getting an error.

On the second line we are assigning the reference of an anonymous function to functionOne.

The second case is of function declarations that loads before any code is executed. So if you do like the following you won't get any error as the declaration loads before code execution.

functionOne();
function functionOne() {
   // Some code
}

@varna 2015-09-09 10:30:53

I'm listing out the differences below:

  1. A function declaration can be placed anywhere in the code. Even if it is invoked before the definition appears in code, it gets executed as function declaration is committed to memory or in a way it is hoisted up, before any other code in the page starts execution.

    Take a look at the function below:

    function outerFunction() {
        function foo() {
           return 1;
        }
        return foo();
        function foo() {
           return 2;
        }
    }
    alert(outerFunction()); // Displays 2
    

    This is because, during execution, it looks like:-

    function foo() {  // The first function declaration is moved to top
        return 1;
    }
    function foo() {  // The second function declaration is moved to top
        return 2;
    }
    function outerFunction() {
        return foo();
    }
    alert(outerFunction()); //So executing from top to bottom,
                            //the last foo() returns 2 which gets displayed
    

    A function expression, if not defined before calling it, will result in an error. Also, here the function definition itself is not moved to the top or committed to memory like in the function declarations. But the variable to which we assign the function gets hoisted up and undefined gets assigned to it.

    Same function using function expressions:

    function outerFunction() {
        var foo = function() {
           return 1;
        }
        return foo();
        var foo = function() {
           return 2;
        }
    }
    alert(outerFunction()); // Displays 1
    

    This is because during execution, it looks like:

    function outerFunction() {
       var foo = undefined;
       var foo = undefined;
    
       foo = function() {
          return 1;
       };
       return foo ();
       foo = function() {   // This function expression is not reachable
          return 2;
       };
    }
    alert(outerFunction()); // Displays 1
    
  2. It is not safe to write function declarations in non-function blocks like if because they won't be accessible.

    if (test) {
        function x() { doSomething(); }
    }
    
  3. Named function expression like the one below, may not work in Internet Explorer browsers prior to version 9.

    var today = function today() {return new Date()}
    

@SantiBailors 2015-10-05 12:58:33

@Arjun What's the problem if a question was asked years earlier ? An answer doesn't only benefit the OP but potentially all SO users, no matter when the question was asked. And what's wrong with answering questions that already have an accepted answer ?

@Sudhansu Choudhary 2015-10-18 21:37:08

@Arjun you got to understand answering old questions is not bad. If it were to be, SO would have had such a barrier. Imagine there is a change in API(albeit not in this question's context) and someone spots it and provides an answer with the new API, shouldn't that be allowed?? Until and unless the answer doesn't make sense and doesn't belong here, it would be downvoted and removed automatically. You don't need to bother with it!!!!

@Rohan 2015-07-21 07:45:37

Greg's Answer is good enough, but I still would like to add something to it that I learned just now watching Douglas Crockford's videos.

Function expression:

var foo = function foo() {};

Function statement:

function foo() {};

The function statement is just a shorthand for var statement with a function value.

So

function foo() {};

expands to

var foo = function foo() {};

Which expands further to:

var foo = undefined;
foo = function foo() {};

And they are both hoisted to the top of the code.

Screenshot from video

@Thomas Heymann 2015-10-05 16:25:35

Sorry but this is incorrect - I don't know what Crockford is trying to say in that slide. Both function & variable declarations are always hoisted to top of their scope. The difference is that variable assignments (whether you are assigning it with a string, boolean or function) are not hoisted to the top whereas function bodies (using function declaration) are.

@Thomas Heymann 2015-10-05 16:51:24

Have a look at these code examples: gist.github.com/cyberthom/36603fbc20de8e04fd09

@Tao 2015-06-24 10:08:07

This is just two possible ways of declaring functions, and in the second way, you can use the function before declaration.

@Jack Giffin 2018-05-10 21:06:22

Please elaborate and provide working code snippets

@NullPoiะธteั 2013-01-05 18:37:52

The first one (function doSomething(x)) should be part of an object notation.

The second one (var doSomething = function(x){ alert(x);}) is simply creating an anonymous function and assigning it to a variable, doSomething. So doSomething() will call the function.

You may want to know what a function declaration and function expression is.

A function declaration defines a named function variable without requiring variable assignment. Function declarations occur as standalone constructs and cannot be nested within non-function blocks.

function foo() {
    return 3;
}

ECMA 5 (13.0) defines the syntax as
function Identifier ( FormalParameterListopt ) { FunctionBody }

In above condition the function name is visible within its scope and the scope of its parent (otherwise it would be unreachable).

And in a function expression

A function expression defines a function as a part of a larger expression syntax (typically a variable assignment ). Functions defined via functions expressions can be named or anonymous. Function expressions should not start with โ€œfunctionโ€.

// Anonymous function expression
var a = function() {
    return 3;
}

// Named function expression
var a = function foo() {
    return 3;
}

// Self-invoking function expression
(function foo() {
    alert("hello!");
})();

ECMA 5 (13.0) defines the syntax as
function Identifieropt ( FormalParameterListopt ) { FunctionBody }

@Herc 2012-11-29 11:28:49

I use the variable approach in my code for a very specific reason, the theory of which has been covered in an abstract way above, but an example might help some people like me, with limited JavaScript expertise.

I have code that I need to run with 160 independently-designed brandings. Most of the code is in shared files, but branding-specific stuff is in a separate file, one for each branding.

Some brandings require specific functions, and some do not. Sometimes I have to add new functions to do new branding-specific things. I am happy to change the shared coded, but I don't want to have to change all 160 sets of branding files.

By using the variable syntax, I can declare the variable (a function pointer essentially) in the shared code and either assign a trivial stub function, or set to null.

The one or two brandings that need a specific implementation of the function can then define their version of the function and assign this to the variable if they want, and the rest do nothing. I can test for a null function before I execute it in the shared code.

From people's comments above, I gather it may be possible to redefine a static function too, but I think the variable solution is nice and clear.

@thomasrutter 2010-04-20 04:54:49

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 first variant (var functionOne = function() {}), that function can only be called after that point in the code.

With the second variant (function functionTwo()), the function is available to code that runs above where the function is declared.

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

More technical information

JavaScript has three ways of defining functions.

  1. Your first 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,
  2. Your second 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.
  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.

@Sasha Firsov 2010-01-23 20:32:54

In terms of code maintenance cost, named functions are more preferable:

  • Independent from the place where they are declared (but still limited by scope).
  • More resistant to mistakes like conditional initialization (you are still able to override if wanted to).
  • The code becomes more readable by allocating local functions separately of scope functionality. Usually in the scope the functionality goes first, followed by declarations of local functions.
  • In a debugger you will clearly see the function name on the call stack instead of an "anonymous/evaluated" function.

I suspect more PROS for named functions are follow. And what is listed as an advantage of named functions is a disadvantage for anonymous ones.

Historically, anonymous functions appeared from the inability of JavaScript as a language to list members with named functions:

{
    member:function() { /* How do I make "this.member" a named function? */
    }
}

@Sasha Firsov 2010-02-04 00:45:03

There are the test to confirm: blog.firsov.net/2010/01/… JS performance test - scope and named functions - Analytics

@sla55er 2014-06-05 08:28:44

The first example is a function declaration:

function abc(){}

The second example is a function expression:

var abc = function() {};

The main difference is how they are hoisted (lifted and declared). In the first example, the whole function declaration is hoisted. In the second example only the var 'abc' is hoisted, its value (the function) will be undefined, and the function itself remains at the position that it is declared.

To put it simply:

//this will work
abc(param);
function abc(){}

//this would fail
abc(param);
var abc = function() {}

To study more about this topic I strongly recommend you this link

@GôTô 2014-06-05 08:34:58

Your example is kind of the same as the top answer

@sla55er 2014-06-08 05:44:23

The main reason for posting this answer was to provide the link at the bottom. This was the piece that was missing for me to fully understand the above question.

@XML 2015-01-13 00:26:03

It's very cool that you wanted to share the link. But links to additional information, in SO, should just be a comment on either the question or your favorite answer. It's very much sub-optimal to clutter a long, complicated page like this with repeated information just to add a single useful link at the end of it. No, you won't get rep points for providing the link, but you'll be helping the community.

@Leon Gaban 2015-05-01 15:06:55

I'm adding my own answer just because everyone else has covered the hoisting part thoroughly.

I've wondered about which way is better for a long while now, and thanks to http://jsperf.com now I know :)

enter image description here

Function declarations are faster, and that's what really matters in web dev right? ;)

@Richard Garside 2015-05-02 15:22:58

I'd say that maintainability is the most important aspect of most code. Performance is important, but in most cases IO is likely to be a bigger bottleneck that the way you define your functions. However there are some problems where you need every bit of performance you can get and this is useful in those cases. Also good to have an answer here that answers clearly a well defined part of the question.

@Sandeep Nayak 2015-11-17 14:15:48

Well, I found it to be other way around with Firefox. jsperf.com/sandytest

@gavenkoa 2016-01-10 15:13:21

Microbenchmarks always fail. Looking to jsperf.com is waster of time. What you really need is to look to JS engine source code, official documentation, or at least sniff dev blogs or mail lists.

@Leon Gaban 2016-12-28 16:56:35

Just an update, since I've gone full functional programming style in JavaScript now, I never use declarations, only function expressions so I can chain and call my functions by their variable names. Check out RamdaJS...

@ocramot 2017-01-10 13:40:22

@SandeepNayak I just run your own test in Firefox 50.0.0 / Windows 7 0.0.0, and it actually is the same way as Leon's. So if your test is correct, I would conclude that jsperf's tests are not indicatives, and it all depend on your browser and / or OS version, or in the particular state of the current machine in that particular moment.

Related Questions

Sponsored Content

42 Answered Questions

[SOLVED] Is there an "exists" function for jQuery?

  • 2008-08-27 19:49:41
  • Jake McGraw
  • 727741 View
  • 2664 Score
  • 42 Answer
  • Tags:   javascript jquery

33 Answered Questions

[SOLVED] What's the difference between using "let" and "var"?

31 Answered Questions

25 Answered Questions

[SOLVED] Set a default parameter value for a JavaScript function

31 Answered Questions

[SOLVED] What's the difference between a method and a function?

19 Answered Questions

10 Answered Questions

[SOLVED] What does the exclamation mark do before the function?

  • 2010-09-20 21:21:51
  • Sebastian Otto
  • 155131 View
  • 1187 Score
  • 10 Answer
  • Tags:   javascript function

28 Answered Questions

[SOLVED] Is there a better way to do optional function parameters in JavaScript?

7 Answered Questions

[SOLVED] How do you pass a function as a parameter in C?

3 Answered Questions

[SOLVED] JavaScript plus sign in front of function name

Sponsored Content