60

When a local (inner) function is declared in JavaScript, there are two options:

Declaring with var keyword, assigning to the variable:

(function() {
    var innerFunction1 = function() { ... };
    innerFunction1();
}());

Declaring just with the function keyword, without assigning to variable:

(function() {
    function innerFunction2() { ... };
    innerFunction2();
}());

I can see one advantage of the second: the function can be declared below the code which calls it so it is easier to separate private functions from the code actually executed.

Which of them is better and why?

Pavel S.
  • 11,892
  • 18
  • 75
  • 113
  • 5
    Possibly already answered here: [JavaScript: var functionName = function() {} vs function functionName() {}](http://stackoverflow.com/q/336859/254830). The earlier one is asking for pros and cons and not which is better, however there doesn't appear to be a better necessarily. – doppelgreener May 15 '13 at 01:38
  • 1
    This answer may help you understand the differences between the two way of declaring a function : http://stackoverflow.com/questions/3887408/javascript-function-declaration-and-evaluation-order – OXMO456 May 18 '13 at 23:45
  • The first one (var) assigns a pointer to an anonymous function to the variable, and the second one defines a named function. I am not sure what impact this may have ( memory use etc ) just thought it was worth pointing out.. – Michael Coxon May 19 '13 at 09:24

11 Answers11

49

Actually there are 3 ways to declare a function:

  1. Function declaration: 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. ex: function innerFunction1 () { };

  2. Function expression:: A Function Expression defines a function as a part of a larger expression syntax (typically a variable assignment). Functions defined via Function Expressions can be named or anonymous:

    a. Using an anonymous function - var innerFunction1 = function() { };

    b. Using a named function - var innerFunction1 = function myInnerFunction () { };

  3. Function constructor: A Function Constructor defines a function dynamically using the Function( ) constructor. Note that the function body is passed to the function as a string argument. var innerFunction1 = new Function (arg1, arg2, ... argN, functionBody)

The third method is not recommended because passing the function body as a string may prevent some JS engine optimizations, and it is prone to errors.

The differences between function declaration and function expression are subtle and you should choose whichever method suits your requirements best.

I use function expression where I need

  1. a singleton function, or
  2. to determine which function to use programmatically (using a named function expression).

Some differences between a function declaration and a function expression are:

  1. Function expressions allow you to assign different functions to the same variable at different points.
  2. A function defined by a function declaration can be used before the function declaration itself (or basically anywhere in the current scope), whereas a function defined by a function expression can only be used after the point it is defined.

Click here to read the detailed comparison of Function Declaration vs Function Expression vs Function Constructor @MDN

Note: A function declaration can be easily turned into a function expression by assigning it to a var.

function foo() {}
alert(foo); // alerted string contains function name "foo"
var bar = foo;
alert(bar); // alerted string still contains function name "foo"

More Reading:

Community
  • 1
  • 1
Selvakumar Arumugam
  • 79,297
  • 15
  • 120
  • 134
  • 2
    Difference 1 is not true. Even if you use function declaration you can still override the definition by using a subsequent function expression. `function a() { alert("a"); } a = function () { alert("b"); }; a(); // gives "b" not "a"` – Halcyon May 18 '13 at 01:53
  • 1
    Difference 2 is not true. `var a, b; a = function () { b(); }; b = function () { alert("b"); }; a(); // prints "b" not "ReferenceError: b is not defined"` – Halcyon May 18 '13 at 01:55
  • 1
    @FritsvanCampen Difference 2: The difference actually lies on when the browser loads them into the execution context which is mentioned in point 2. See the difference `var a, b; a = function () { b(); }; a(); b = function () { alert("b"); };` and `var a; a = function () { b(); }; a(); function b() { alert("b"); };`. In version 1: function b is defined as function expression which would throw an error while version 2 is a function declaration which would work fine as it is already initialized. – Selvakumar Arumugam May 18 '13 at 03:22
  • @FritsvanCampen Difference 1: It means you can achieve a behavior like polymorphism programmatically where you can defined which function it will execute at run time. You should read the link posted in MDN which has more details and examples. – Selvakumar Arumugam May 18 '13 at 03:33
  • 1
    About diff-1 polymorphism isn't the right word, we're not dealing with prototypes here. You can reassign a function even if you use function declaration notation (so diff 1 is moot), see my answer. About diff-2, your version-1 and version-2 are not equivalent. You changed the order of the statements. Function definitions get moved to the top, like their declaration. That's a _trick_, it's _convenient_. I don't think you've explained that sufficiently. – Halcyon May 18 '13 at 11:49
  • @FritsvanCampen Which part are you not clear `behavior like` in diff 1 or `when the browser loads` and how is that a trick when it clearly shows `undefined` in version 1 and in version 2 it is defined. Yes, both the versions are different and the difference is the order at which they are exposed and that is the difference I am trying to explain... I believe the 2nd point has been explained clear enough. – Selvakumar Arumugam May 18 '13 at 15:46
  • @FritsvanCampen And yes, you can demonstrate polymorphism behavior without using prototype but I agree that reassigning a var there is not a good demonstration. – Selvakumar Arumugam May 18 '13 at 16:00
  • What on earth is "a singleton function"? Presumably you mean "a singleton", though that still wouldn't make sense. – Beetroot-Beetroot May 22 '13 at 08:34
  • @Beetroot-Beetroot Could you mention why it doesn't make sense? – Selvakumar Arumugam May 22 '13 at 14:06
  • Because "singleton" is really a "singleton pattern", involving (in javascript) the assignment of something returned by a function, not the assignment of the function itself. Now, I agree that the returned "something" could itself be a function, but that is a special case, not a generality. – Beetroot-Beetroot May 22 '13 at 18:52
  • @Vega I just added an answer where I highlight the main reasons why I advise to always use `function expressions` considering the many cons using `function declarations` bring. Feedback welcome :) – Adriano Nov 05 '14 at 17:03
  • the OP asked this for an inner function, so the question is probably about the scope of either declaration, not about any other differences. There is the slight chance that function innerFunction() declares a global function like introducing a variable in a function without var makes it global, while var innerFunction= is definitely local. – Peter Jul 31 '21 at 21:18
8

The two notations are functionally equivalent.

You can assume that:

function a() {}
function b() {}

is interpreted as:

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

This is why you don't have to declare- (not define!) before-use. You can reassign functions after you've defined them, just like you would with a variable. Functions get hoisted just like variables, because they are variables (mind=blown? good!).


Declare-before-use

function a() { b(); } // using b before it's declared?
function b() {}

becomes:

var a, b;
a = function a() { b(); }; // nope! b is declared, we're good
b = function b() {};

Redefining a function

function a() { alert("a"); }
a = function b() { alert("b"); }; // that's weird!

becomes:

var a;
a = function a() { alert("a"); };
a = function b() { alert("b"); }; // oh, that looks normal

Declare vs define

Declare is: var x. In English: "I will be using variable x".

Define is: x = 5. In English "Variable x now has the value 5".

Declare-before-use is required and enforced in "use strict". Define-before-use is not required. If your variables are defined in run-time you're good.

So var x = 5 is both a declaration and a definition, as is function a() {}.

Be cautious when naming functions not to override an existing variable:

var a = function () { alert("a"); };
var b = function a() { alert("b"); };
a(); // prints "b"

Lint tools will pick up on this.


When to use which notation?

I would recommend using the function expression notation (var a = function () {}) only when you are reassigned the value of a later on. The function expression then signals to the reader that a is going to get reassigned and that it is intentional.

Another (minor) argument for the function expression notation is a Lint tool like JSLint that might require you to declare (not define!) your functions before you use them. If you have functions with a recursive definition, ie. a calls b and b calls a, you can not declare one before the other by using the function declaration notation.

Edit notes: I've made a slight revision about named anonymous functions. It can be usefull to name anonymous functions when you're looking at a stacktrace. The named function will give more context lest it be logged as 'anonymous'.

Halcyon
  • 57,230
  • 10
  • 89
  • 128
  • 1
    Naming anonymous functions is useless unless you intend to call the function from itself. It can be potentially dangerous to name an anonymous function the same as a previously defined function. Consider this example: `var a = function(){ alert("!"); }; var b = function a() { a() }; b();`. It is an infinite recursion. Bottom line, don't name your anonymous functions unless you intend to recurse them, and especially don't re-use a name which is already present in the same scope. – Travis J May 18 '13 at 17:54
  • I can't say I disagree. The named anonymous functions are expansions. They must be expanded with their name or the `toString` will not be similar. I agree that there is no need to name anonymous functions and that there is a potential for bugs; but again, that is the expanded form, not what you should be writing. I can amend it if you think it's not sufficiently clear. – Halcyon May 18 '13 at 22:41
  • I do disagree.. placing functions named off of a global object allows a sort of [namespacing](http://stackoverflow.com/questions/3750082/javascript-oop-best-practices/13074081#13074081) and calling the function or object containing functionality from a variety of places.. – Brett Weber May 19 '13 at 02:11
  • I'm not sure what you mean. This isn't so much about keeping sensible function names and namespaces, it's about accidentally overriding a variable by naming a function. – Halcyon May 19 '13 at 11:39
4

The difference is that function with VAR is defined at run-time,

whereas function() without VAR is defined at parse-time for a script block.

That is the only major difference..

So, user will decide on the requirement basis, which to use, and which suits the requirement..

MarmiK
  • 5,639
  • 6
  • 40
  • 49
  • 1
    i agree with you, this is the most important fact ! – OXMO456 May 19 '13 at 00:03
  • I'm not sure if this is actually true. It would seem to me that the transformation phase changes one form to the other. Can you post a source to back up your claim? – Halcyon May 19 '13 at 11:43
2

There is not any difference in output. Both can still be invoked and both can have their prototype accessed by name.

There are only two real differences.

1) Readability and preference

Some people find one way easier to read than others, and they will in turn base their convention on that style. Following convention is important.

2) Slight space saver

With minification being ever more relevant for scripts, you can see how it might be advantageous to use the second approach as it does not require the use of var or = which will save a basically insignificant 4 characters of space in your minified script.


Executive Summary

It all comes down to preference. Which is better? You tell me. Personally, I will use var if I intend to make an object out of it with new and then I will capitalize the first letter, such as Person. Otherwise, I tend to camelCase it and omit the use of var.

Travis J
  • 81,153
  • 41
  • 202
  • 273
  • 1
    The minification argument is moot. If you use a compressor such as Google's Closure Compiler or Yahoo's YUI Compressor all variables get shorter names and code gets optimized. Source code should be made first and foremost to be readable, leave the minifying to the machine. – Halcyon May 18 '13 at 01:47
  • @FritsvanCampen - Did you even try before you stated the argument was moot? Where is your evidence? What did you attempt to do in order to make your assertion? What do you think `function a(){}var b = function(){};` gets compressed to? YUI compresses that to `function a(){}var b=function(){};`. You can see how `function a`'s declaration is actually less code. Furthermore, please refer to the comment in my answer which states this difference is "basically insignificant". – Travis J May 18 '13 at 17:21
  • Your argument is: "this form is shorter to write so it's better". Even if you mean it's only _slightly_ better or "basically insignificant[ly]" better you're still saying that shorter is better and that is something I can't agree with. Another thing that bothers me is that you labelled your "insignificant" argument at the same level as the readability/style argument. If you took out the numbering I wouldn't mind so much. Just constructive criticism, no hard feelings :) – Halcyon May 19 '13 at 11:53
1
  • var without function name

    • is better if you master your variable declarations: especially when they are declared.


  • Function named without var:

    • implies a so named variable declaration at the beginning of the current scope and it may prevent from some errors,
    • but: declaring a function this way, using a closure variable declared with var will fail if this function is called before the closure variable is even declared. So, you have to know what you do.


  • Function named with or without var

    • is good for class declaration,
    • and for profiling cause, for instance, Chrome dev profiling tool will be more explicit if functions are not anonymous: they will have an explicit name and you will know where is the slow part of your code.


  • Function named and with var

    • is the way to have the function as a named scope without having the declared variable as a closure
    • while keeping the mastering of variable declaration order.
atondelier
  • 2,424
  • 15
  • 11
1

Local declarations should always use var.

Well I would say that first is better since it is a local scope and memory could be cleared after symbol not more in use.

There is also a note on google javascript style guide saying that the second form is not part of standard so it should not be used.

Function Declarations Within Blocks

Do not do this:

if (x) { function foo() {} } While most script engines support Function Declarations within blocks it is not part of ECMAScript (see ECMA-262, clause 13 and 14). Worse implementations are inconsistent with each other and with future EcmaScript proposals. ECMAScript only allows for Function Declarations in the root statement list of a script or function. Instead use a variable initialized with a Function Expression to define a function within a block:

if (x) {

var foo = function() {}

}

Source http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml .

Community
  • 1
  • 1
cavila
  • 7,834
  • 5
  • 21
  • 19
  • 1
    All modern browsers support both variants and it is extremely unlikely that they will drop support in the future, because it would break lots of existing code. Using function foo instead of var foo can improve the display of function names in a debugger. – Zotta May 17 '13 at 21:17
  • Defining variables (and functions) inside block statements is considered bad practice. For instance: `if (bool) { var x = "y"; } else { var x = "z"; }` because of variable hoisting you will have declared `x` twice. – Halcyon May 18 '13 at 01:43
1

Agree with @MarmiK. Also the difference between two methods is the scope. While function declaration assigns local scope by default, the scope of the function assigned to a variable depends on the scope of the variable.

var a;
(function() {
    var innerFunction1 = function() { ... };//local scope
    a=innerFunction1;//assigning to a global variable
}());

can be accessed globally. Go with the function declaration if you dont need to change the scope. https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope

EDIT:

var a;
(function() {
    function innerFunction1() { ... };//local scope
    a=innerFunction1;//It works too(Don't know why it should though)
}());

So, as pointed out by @Frits, there seems to be no scope advantage in using one type over the other.

Binu Pandian
  • 163
  • 4
  • There is no difference is scope, functions get hoisted just like variables. – Halcyon May 18 '13 at 01:41
  • @Frits Is that so? I thought inner functions can only be accessed through their parent function.Can you post some links that explains it? – Binu Pandian May 18 '13 at 10:58
  • You can do `a=innerFunction1` even if you use function declaration notation. Just try it. – Halcyon May 18 '13 at 11:43
  • @Frits I guess I was fixated with the idea that functions could not (or should not) be passed directly in this way.Thanks for clearing me out. – Binu Pandian May 20 '13 at 09:57
0

Zakas says that "As long as you always define functions before they used, you can feel free to use either function declarations or function expressions."

It means, if your code will be changed tomorrow by another person you dont know some day, and it is a big project that the developer cant find where the function is declared, you must use function declaration ( i mean function x(){} ), or if you declare the functions first anyway, you can use expressions.

cenk ebret
  • 687
  • 4
  • 15
0

I think that everybody who starts programming in JavaScript asks the question to themselves sooner or later. I would reformulate your question to:

Should I use (prefer to use) function declaration (function statement) or function expression (var version)?

In the most cases one can write good JavaScript code using only one from the constructions. It's clear that there are some important differences in semantic, but I want to stress, that in my opinion the answer on the question is mostly the answer about the style of the program. So I would answer that in the most real cases the choice is the matter of the taste.

The persons who prefer to use function statement use it mostly not while they need define readonly function variable and not why they don't want to declare it before it will be used. In my opinion one uses it so mostly because one likes the form.

So I think that there are no objectively correct answer on your question. The choice is subjective. So I write in my answer which construction I personally prefer and in which situations.

My first languages were Pascal, C, Fortran, C++ etc. I used to use C# now. So when I started to write JavaScript programs I used at the beginning my existing style of writing of programs from another languages. Later I changed the style of my JavaScript code corresponds to specific of the language.

I personally prefer to use function expression style and I declare all the functions in the first statement of the outer function. I find that the form mostly clear to JavaScript semantic where the name of the function is variable contains a function value. The name of the function is subject to hoisting like any other variable. For example my code look like below

(function() {
    "use strict";
    var myFunc1 = function (x) {
            // body where I can use x and this
            alert("x=" + x + ", this.foo=" + this.foo);
        },
        localVar1 = {foo: "bar"};

    myFunc1.call(localVar1, 1);
}());

I use function statement very seldom and only if I declare the constructor of the class like:

(function() {
    "use strict";
    function MyClass(x) {
        // the code of constructor
        this.abc = x;
    }
    var myInstance = new MyClass("xyz");
    alert(myInstance.abc);
}());

I try never use the third form:

(function() {
    "use strict";
    var myFunc1 = function myFunc2(x) {
            ...
        };
    ...    
}());

where myFunc2 are declared additionally to myFunc1. The implementation of such form depends from web browser. It has sense probably in case of usage recursive functions.

Oleg
  • 220,925
  • 34
  • 403
  • 798
0

Defining a javascript function

As mentioned by Vega, there are 3 ways of defining a function:

  1. function constructor
  2. function declaration
  3. function expression

Cons of Function constructor:

Function constructors needs the function body as a string which:

  • may prevent some JS engine optimizations
  • makes the syntax incredibly hard to write: need to escape special characters & some other madness, see below

    var foo = (new Function("var bar = \'FOO!\';\nreturn(function() {\n\talert(bar);\n});"))();

    foo(); // The segment "function() {\n\talert(bar);\n}" of the function body string is not re-parsed.

Cons of Function declaration:

It can be invoked before the function declaration itself, this actually introduces complexity:

Pros of Function expression:

Function expressions are simpler:

  • you "just know" what variable it is assigned to
  • you cannot invoke/reference the variable to which the function is assigned to before its definition, which is a consistent behavior with the rest of the javascript definitions

More about: Converting function declarations into function expressions

Danger: As mentioned in "Cons of Function declaration" this can lead to many issues, below are more details about this.

It is very easy to convert function declarations into function expressions.

"A function declaration ceases to be one when it either: becomes part of an expression is no longer a "source element" of a function or the script itself. A "source element" is a non-nested statement in the script or a function body"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Examples_2

"function statements are subject to hoisting. This means that regardless of where a function is placed, it is moved to the top of the scope in which it is defined. This relaxes the requirement that functions should be declared before used, which I think leads to sloppiness. It also prohibits the use of function statements in if statements. It turns out that most browsers allow function statements in if statements, but they vary in how that should be interpreted. That creates portability problems." - from the book: Javascript The Good Parts


More about function expressions

Syntax is such as:

 var varName = function [name]([param] [, param] [..., param]) {    /* function expression */
      statements
 }

Things to note about [name] (just after "function" in Syntax):

  • The function name can be omitted, in which case the function becomes known as an anonymous function.
  • "A function name cannot be changed, while the variable the function is assigned to can be reassigned."
  • "The function name can be used only within the function's body." , you can use this feature to let the function call itself recursively.

Then using [name] you can do strange/funny things such as below. Note that I do not recommend doing this if you are new to function definitions.

var count = 0;

var varName = function funcName() {    /* function expression */
  console.log('count is: ' + count );
  if(count<1){
    count++;
    funcName();   /* calls function funcName another time  */
  }
};

varName();    // invokes function funcName via variable varName
funcName();   // throws an error as funcName is not reachable

see live demo on jsbin.com/gijamepesu/1/edit?js,console

A typical implementation & usage would be such as below.

 var myCoolFunc = function ( username, firstName, lastName ) {    /* function expression */
      console.log('user ' + username + ' has the real full name ' + firstName + ' ' + lastName);
 }

 myCoolFunc();

Another thing to note: function expressions can be immediately invoked, vs function declarations cannot. This feature is used in IIFE, read more on What is the purpose of wrapping whole Javascript files in anonymous functions like “(function(){ … })()”?


Resources

Community
  • 1
  • 1
Adriano
  • 19,463
  • 19
  • 103
  • 140
-3

Short answer: It doesn't matter in the code, but you should put var to make it more readable.

Long answer: Local variables in JavaScript, just like global variables in JavaScript, can be defined with or without var. Therefore, the function of the program will not be interfered by the lack or presence of the word var. Because it is easier to read code with var, it is suggested that you do put var before variables when they are first declared. But if you want it to be unreadable, then you should not put var before defining a variable.

Qvcool
  • 460
  • 3
  • 10
  • 3
    -1 This doesn't appear to be responding to the question. The asker is not talking about whether to use `var` or not when defining variables. The asker is asking how functions should be declared (`var func = function() {...}` vs `function func() {...}`). – doppelgreener May 15 '13 at 00:16