var functionName = function() {} vs function functionName() {}
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:
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?
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:
And, a function declaration:
This also means you can't conditionally define functions using function declarations:
The above actually defines functionThree
irrespective of test
's value — unless use strict
is in effect, in which case it simply raises an error.
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:
Secondly, it is possible to combine both styles:
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:
If you want to alias functions on all browsers, use this kind of declaration:
In this case, both xyz
and abc
are aliases of the same object:
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
its name is automatically assigned. But when you define it like
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:
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:
abc
here is defined everywhere in the current scope:
Also, it hoisted through a return
statement:
This is a function expression:
xyz
here is defined from the point of assignment:
Function declaration vs. function expression is the real reason why there is a difference demonstrated by Greg.
Fun fact:
Personally, I prefer the "function expression" declaration because this way I can control the visibility. When I define the function like
I know that I defined the function locally. When I define the function like
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
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.
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+)
The first form is a function declaration, which looks like this:
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:
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:
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:
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:
The second common form is called an anonymous function expression:
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.)
The third form is a named function expression ("NFE"):
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:
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.)
Sometimes functions can sneak in largely unnoticed; that's the case with accessor functions. Here's an example:
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
.
ES2015 brings us the arrow function. Here's one example:
See that n => n * 2
thing hiding in the map()
call? That's a function.
A couple of things about arrow functions:
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.
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:
(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:
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.)
ES2015 allows a shorter form of declaring a property that references a function; it looks like this:
the equivalent in ES5 and earlier would be:
ES2015 brings us class
syntax, including declared constructors and methods:
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
.
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:
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.:
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.
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.
A better explanation to Greg's answer
Why no error? We were always taught that expressions are executed from top to bottom(??)
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:
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:
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:
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.)
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
, this definition of myfunction
will override any previous definition, since it will be done at parse-time.
While
does the correct job of defining myfunction
only when condition
is met.
An important reason is to add one and only one variable as the "Root" of your namespace...
or
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?
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
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.
Function
Default return value of function is 'undefined', Variable declaration default value also 'undefined'
Function Declaration
Function Expression
Function assigned to variable Example:
javascript interpreted as
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.
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
.
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 :)
Function declarations are faster, and that's what really matters in web dev right? ;)
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 toundefined
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...
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 declarations take precedence over variable declarations, and the last function declaration "sticks".
In this example a
is initialized with the function object resulting from evaluating the second function declaration, and then is assigned 4
.
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
.
The first example is a function declaration:
The second example is a function expression:
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:
To study more about this topic I strongly recommend you this
link
In terms of code maintenance cost, named functions are more preferable:
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:
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.
In computer science terms, we talk 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 information on anonymous functions and lambda calculus, Wikipedia is a good start (http://en.wikipedia.org/wiki/Anonymous_function).
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:
Function statement:
The function statement is just a shorthand for var
statement with a function
value.
So
expands to
Which expands further to:
And they are both hoisted to the top of the code.
@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)
If you name the function that will be called recursively, the tests will pass. (page 14)
Another difference that is not mentioned in the other answers is that if you use the anonymous function
and use that as a constructor as in
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
it is possible to retrieve the name of the constructor as a string with two.constructor.name
.
If you would use those functions to create objects, you would get:
I'm listing out the differences below:
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:
This is because, during execution, it looks like:-
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:
This is because during execution, it looks like:
It is not safe to write function declarations in non-function blocks like if because they won't be accessible.
Named function expression like the one below, may not work in Internet Explorer browsers prior to version 9.
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.
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”.
ECMA 5 (13.0) defines the syntax as
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
In light of the "named functions show up in stack traces" argument, modern JavaScript engines are actually quite capable of representing anonymous functions.
As of this writing, V8, SpiderMonkey, Chakra and Nitro always refer to named functions by their names. They almost always refer to an anonymous function by its identifier if it has one.
SpiderMonkey can figure out the name of an anonymous function returned from another function. The rest can't.
If you really, really wanted your iterator and success callbacks to show up in the trace, you could name those too...
But for the most part it's not worth stressing over.
In JavaScript there are two ways to create functions:
Function declaration:
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.
Function expression:
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() {}
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.
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.
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
FireFox 55
Chrome Canary 63.0.3225
Anonymous
function expressions appear to have better performance
against Named
function expression.
Firefox
Chrome Canary
Chrome
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
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
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
There are three noteworthy comparisons between the two different declarations of functions as listed below.
The following works because function add()
is scoped to the nearest block:
The following does not works (because the var add=
superseeds the function add()
).
The following does not work because add
is declared after it is used.
The name of a function function thefuncname(){}
is thefuncname when it is declared this way.
Otherwise, if a function is declared as function(){}
, the function.name is the first variable used to store the function.
If there are no variables set to the function, then the functions name is the empty string (""
).
Lastly, while the variable the function is assigned to initially sets the name, successive variables set to the function do not change the name.
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).
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.
This is just two possible ways of declaring functions, and in the second way, you can use the function before declaration.
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.
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?