Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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?

share|improve this question
24  
permadi.com/tutorial/jsFunc/index.html is very good page about javascript functions – uzay95 Apr 9 '10 at 11:51
10  
Related is this excellent article on Named Function Expressions. – Phrogz Apr 21 '11 at 21:30
2  
@CMS references this article: kangax.github.com/nfe/#expr-vs-decl – Upper Stage Aug 3 '11 at 14:18
4  
There are two things you need to be aware of: #1 In JavaScript, declarations are hoisted. Meaning that var a = 1; var b = 2; becomes var a; var b; a = 1; b = 2. So when you declare functionOne, it gets declared but its value isn't set immediately. Whereas since functionTwo is just a declaration, it gets put at the top of the scope. #2 functionTwo lets you access the name property and that helps a lot when trying to debug something. – xavierm02 Aug 21 '12 at 16:20
2  
Oh and btw, the correct syntax is with a ";" after the assignation and without after the declaration. E.g. function f(){} vs var f = function(){};. – xavierm02 Aug 21 '12 at 16:27
show 6 more comments

14 Answers

up vote 775 down vote accepted

The difference is that functionOne is defined at run-time, whereas functionTwo is defined at parse-time for a script block. For example:

<script>
  // Error
  functionOne();

  var functionOne = function() {
  }
</script>

<script>
  // No error
  functionTwo();

  function functionTwo() {
  }
</script>
share|improve this answer
39  
Thanks for your answer. That helps me understand how they both work. I still need to understand in what circumstances you'd use the two different approaches and what the pros/cons of both are. – Richard Dec 3 '08 at 11:42
65  
@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. – Jason Bunting Aug 5 '11 at 21:18
26  
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/… – Michal Kuklis Nov 14 '11 at 6:03
30  
@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). – Šime Vidas Jan 4 '12 at 0:59
5  
The terminology for this phenomenon is known as hoisting. – Colin Pear Jan 3 at 7:22
show 14 more comments

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

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.

share|improve this answer

A function declaration and a function expression assigned to a variable behave the same once the binding is established.

There is a difference however at how and when the function object is actually associated with its variable. This difference is due to the mechanism called variable hoisting in JavaScript.

Basically, all function declarations and variable declarations are hoisted to the top of the function in which the declaration occurs (this is why we say that JavaScript has function scope).

  • When a function declaration is hoisted, the function body "follows" so when the function body is evaluated, the variable will immediately be bound to a function object.

  • When a variable declaration is hoisted, the initialization does not follow, but is "left behind". The variable is initialized to undefined at the start of the function body, and will be assigned a value at its original location in the code. (Actually, it will be assigned a value at every location where a declaration of a variable with the same name occurs.)

The order of hoisting is also important: function declarations take precedence over variable declarations with the same name, and the last function declaration takes precedence over previous function declarations with the same name.

Some examples...

var foo = 1;
function bar() {
  if (!foo) {
    var foo = 10 }
  return foo; }
bar() // 10

Variable foo is hoisted to the top of the function, initialized to undefined, so that !foo is true, so foo is assigned 10. The foo outside of bar's scope plays no role and is untouched.

function f() {
  return a; 
  function a() {return 1}; 
  var a = 4;
  function a() {return 2}}
f()() // 2

function f() {
  return a;
  var a = 4;
  function a() {return 1};
  function a() {return 2}}
f()() // 2

Function declarations take precedence over variable declarations, and the last function declaration "sticks".

function f() {
  var a = 4;
  function a() {return 1}; 
  function a() {return 2}; 
  return a; }
f() // 4

In this example a is initialized with the function object resulting from evaluating the second function declaration, and then is assigned 4.

var a = 1;
function b() {
  a = 10;
  return;
  function a() {}}
b();
a // 1

Here the function declaration is hoisted first, declaring and initializing variable a. Next, this variable is assigned 10. In other words: the assignment does not assign to outer variable a.

share|improve this answer
1  
You have a bit weird way to place the closing braces. Are you a Python coder? It looks like you try to make Javascript look like Python. I am afraid it is confusing for other people. If I had to maintain your JavaScript code I would let your code through an automatic prettyprinter first. – nalply May 14 at 12:46

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. Its become more important with the plethora of JavaScript modules available.

Also see Javascript Namespace Declaration

share|improve this answer
1  
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. – Andrew Barber May 29 at 21:13

Another difference that is not mentioned in the other answers is that if you use the anonymous function

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

and use that as a constructor as in

var one = new functionOne();

then one.constructor.name will not be defined. Function.name is non-standard but is supported by Firefox, Chrome, other Webkit-derived browsers and IE 9+.

With

function functionTwo() {
    // Some code
}
two = new functionTwo();

it is possible to retrieve the name of the constructor as a string with two.constructor.name.

share|improve this answer
The name in the first case will not be defined because its an anonymous function assigned to a variable. I think the word anonymous was invented for things that don't have their name defined :) – Om Shankar Jan 17 at 6:13
1  
Yes, that was my point, I'll add it to the answer. – Ingo Kegel Jan 17 at 8:47

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 What is a Function Declaration and Function Expression

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 it’s scope and the scope of it’s parent (otherwise it would be unreachable)

and in 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 }

share|improve this answer
explaining down vote is really helpful :) – NullPoiиteя May 28 at 6:37

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, 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, 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.

share|improve this answer

@EugeneLazutkin gives an example where he names an assigned function to be able to use shortcut() as an internal reference to itself. John Resig gives another example - copying a recursive function assigned to another object in his Learning Advanced Javascript tutorial. While assigning functions to properties isn't strictly the question here, I recommend actively trying the tutorial out - run the code by clicking the button in the upper right corner, and double click the code to edit to your liking.

Examples from the tutorial: recursive calls in yell():

Tests fail when the original ninja object is removed. (page 13)

var ninja = { 
  yell: function(n){ 
    return n > 0 ? ninja.yell(n-1) + "a" : "hiy"; 
  } 
}; 
assert( ninja.yell(4) == "hiyaaaa", "A single object isn't too bad, either." ); 

var samurai = { yell: ninja.yell }; 
var ninja = null; 

try { 
  samurai.yell(4); 
} catch(e){ 
  assert( false, "Uh, this isn't good! Where'd ninja.yell go?" ); 
}

If you name the function that will be called recursively, the tests will pass. (page 14)

var ninja = { 
  yell: function yell(n){ 
    return n > 0 ? yell(n-1) + "a" : "hiy"; 
  } 
}; 
assert( ninja.yell(4) == "hiyaaaa", "Works as we would expect it to!" ); 

var samurai = { yell: ninja.yell }; 
var ninja = {}; 
assert( samurai.yell(4) == "hiyaaaa", "The method correctly calls itself." );
share|improve this answer
Just calling this.yell works too :) – minitech Apr 21 at 20:54

First I want to correct RoBorg: 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 IE — 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 IE). Basically when you define a function like this:

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

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

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's call itself recursively:
  shortcut(n - 1);
  // ...
  // let's 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

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 RoBorg.

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 that:

var abc = function(){};

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

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 this 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 browser.

share|improve this answer
28  
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. ;-) – Eugene Lazutkin Jul 26 '09 at 2:52
4  
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". – NVI Dec 3 '09 at 17:43
2  
That what happens when relying on IE's JavaScript behavior. ;-) Thank you for thoroughness --- I'll update the answer. – Eugene Lazutkin Dec 3 '09 at 19:30
6  
If I could upvote this a hundred times I would. Thanks for the in-depth clarification! – HurnsMobile Jun 1 '11 at 20:06
5  
This should be the accepted answer... – Christoph Oct 24 '12 at 9:47
show 5 more comments

Speaking about the global context, both, the var statement and a FunctionDeclaration at the end will create a non-deleteable property on the global object, but the value of both can be overwritten.

The subtle difference between the two ways is that when the Variable Instantiation process runs (before the actual code execution) all identifiers declared with var will be initialized with undefined, and the ones used by the FunctionDeclaration's will be available since that moment, for example:

 alert(typeof foo); // 'function', it's already available
 alert(typeof bar); // 'undefined'
 function foo () {}
 var bar = function () {};
 alert(typeof bar); // 'function'

The assignment of the bar FunctionExpression takes place until runtime.

A global property created by a FunctionDeclaration can be overwritten without any problems just like a variable value, e.g.:

 function test () {}
 test = null;

Another obvious difference between your two examples is that the first function doesn't have a name, but the second has it, which can be really useful when debugging (i.e. inspecting a call stack).

About your edited first example (foo = function() { alert('hello!'); };), it is an undeclared assignment, I would highly encourage you to always use the var keyword.

With an assignment, without the var statement, if the referenced identifier is not found in the scope chain, it will become a deleteable property of the global object.

Also, undeclared assignments throw a ReferenceError on ECMAScript 5 under Strict Mode.

A must read:

Note: This answer has been merged from another question, in which the major doubt and misconception from the OP was that identifiers declared with a FunctionDeclaration, couldn't be overwritten which is not the case.

share|improve this answer
I did not know that functions could be overwritten in JavaScript! Also, that parse order is the big selling point for me. I guess I need to watch how I create functions. – Xeoncross Aug 8 '10 at 19:43
3  
+1 to the "Named function expressions demystified" article. – Jesse Hallett Jul 21 '11 at 1:14
+1 to the "Named function expressions demystified" article. – Upper Stage Aug 3 '11 at 14:34
+0 to the "Names function expressions demystified" article as it's 404ing. Possible mirror?: kangax.github.com/nfe – Mr_Chimp Nov 29 '11 at 15:10
1  
@Mr_Chimp, thanks, I've updated the article link. – CMS Nov 29 '11 at 15:22
show 2 more comments

Other commenters have already covered the semantic difference of the two variants above. I wanted to note a stylistic difference: Only the "assignment" variation can set a property of another object.

I often build javascript modules with a pattern like this:

(function(){
        var exports = {};

        function privateUtil() {
                ...
        }

        exports.publicUtil = function() {
                ...
        };

        return exports;
})();

With this pattern, your public functions will all use assignment, while your private functions use declaration.

(Note also that assignment should require a semicolon after the statement, while declaration prohibits it.)

share|improve this answer
where i can learn about this pattern ? Could you send to me [email protected] . Thanks – Chameron Jun 3 '11 at 3:25
1  
yuiblog.com/blog/2007/06/12/module-pattern is the primordial reference for the module pattern, as far as I can tell. (Though that article uses the var foo = function(){...} syntax even for private variables. – Sean McMillan Jun 3 '11 at 12:32
The yuiblog link is what I was looking for, thanks. – Priyank Bolia Mar 24 '12 at 14:32
This isn't entirely true in some older versions of IE, actually. (function window.onload() {} was a thing.) – minitech Apr 21 at 19:42
1  
@minitech Horrifying! – Sean McMillan Apr 22 at 13:59

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, that function can only be called after that point in the code.

With the second variant, 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 info

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.
share|improve this answer

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

  • independent from 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 debugger you will clearly see on call stack the function name instead of "anonymous/evaluated" function.

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

Historically anonymous functions appeared from inability of JS as language to list members with named functions:

{ member:function(){/* how to make this.member a named function? */} }

share|improve this answer
1  
There are the test to confirm: blog.firsov.net/2010/01/… JS performance test - scope and named functions - Analytics – Sasha Firsov Feb 4 '10 at 0:45

In computer science terms, we are talking about anonymous functions and named functions. I think the most important difference is that an anonymous function is not bound to an name, hence the name anonymous function. In Javascript it is a first class object dynamically declared at runtime.

For more informationen on anonymous functions and lambda calculus, Wikipedia is a good start (http://en.wikipedia.org/wiki/Anonymous_function).

share|improve this answer

protected by NullPoiиteя Jun 10 at 5:05

This question is protected to prevent "thanks!", "me too!", or spam answers by new users. To answer it, you must have earned at least 10 reputation on this site.

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