This question already has answers here:
var functionName = function() {} vs function functionName() {}
(41 answers)
Closed 9 years ago.
What is the difference between the following lines of code?
//Function declaration
function foo() { return 5; }
//Anonymous function expression
var foo = function() { return 5; }
//Named function expression
var foo = function foo() { return 5; }
Questions:
What is a named/anonymous function expression?
What is a declared function?
How do browsers deal with these constructs differently?
What do the responses to a similar question (var functionName = function() {} vs function functionName() {}) not get exactly right?
They're actually really similar. How you call them is exactly the same.The difference lies in how the browser loads them into the execution context.
Function declarations load before any code is executed.
Function expressions load only when the interpreter reaches that line of code.
So if you try to call a function expression before it's loaded, you'll get an error! If you call a function declaration instead, it'll always work, because no code can be called until all declarations are loaded.
Example: Function Expression
alert(foo()); // ERROR! foo wasn't loaded yet
var foo = function() { return 5; }
Example: Function Declaration
alert(foo()); // Alerts 5. Declarations are loaded before any code can run.
function foo() { return 5; }
As for the second part of your question:
var foo = function foo() { return 5; } is really the same as the other two. It's just that this line of code used to cause an error in safari, though it no longer does.
Function Declaration
function foo() { ... }
Because of function hoisting, the function declared this way can be called both after and before the definition.
Function Expression
Named Function Expression
var foo = function bar() { ... }
Anonymous Function Expression
var foo = function() { ... }
foo() can be called only after creation.
Immediately-Invoked Function Expression (IIFE)
(function() { ... }());
Conclusion
Douglas Crockford recommends to use function expression in his «JavaScript: The Good Parts» book because it makes it clear that foo is a variable containing a function value.
Well, personally, I prefer to use Declaration unless there is a reason for Expression.
Regarding 3rd definition:
var foo = function foo() { return 5; }
Heres an example which shows how to use possibility of recursive call:
a = function b(i) {
if (i>10) {
return i;
}
else {
return b(++i);
}
}
console.log(a(5)); // outputs 11
console.log(a(10)); // outputs 11
console.log(a(11)); // outputs 11
console.log(a(15)); // outputs 15
Edit:
more interesting example with closures:
a = function(c) {
return function b(i){
if (i>c) {
return i;
}
return b(++i);
}
}
d = a(5);
console.log(d(3)); // outputs 6
console.log(d(8)); // outputs 8
The first statement depends on the context in which it is declared.
If it is declared in the global context it will create an implied global variable called "foo" which will be a variable which points to the function. Thus the function call "foo()" can be made anywhere in your javascript program.
If the function is created in a closure it will create an implied local variable called "foo" which you can then use to invoke the function inside the closure with "foo()"
EDIT:
I should have also said that function statements (The first one) are parsed before function expressions (The other 2). This means that if you declare the function at the bottom of your script you will still be able to use it at the top. Function expressions only get evaluated as they are hit by the executing code.
END EDIT
Statements 2 & 3 are pretty much equivalent to each other. Again if used in the global context they will create global variables and if used within a closure will create local variables. However it is worth noting that statement 3 will ignore the function name, so esentially you could call the function anything. Therefore
var foo = function foo() { return 5; }
Is the same as
var foo = function fooYou() { return 5; }
Though the complete difference is more complicated, the only difference that concerns me is when the machine creates the function object. Which in the case of declarations is before any statement is executed but after a statement body is invoked (be that the global code body or a sub-function's), and in the case of expressions is when the statement it is in gets executed. Other than that for all intents and purposes browsers treat them the same.
To help you understand, take a look at this performance test which busted an assumption I had made of internally declared functions not needing to be re-created by the machine when the outer function is invoked. Kind of a shame too as I liked writing code that way.
Related
In Douglas Crockford's book he writes a recursive function as:
var walk_the_DOM = function walk(node, func){
func(node);
node = node.firstChild;
while(node){
walk(node,func);
node = node.nextSibling;
}
}
I've never seen a function defined as var foo = function bar(){...} - I've always seen the right side of the declaration be anonymou as: var foo = function (){...}
Is the only purpose of the name walk in the right side of the declaration to shorten the calling of walk_the_DOM? They seem to become separate names for an identical function. Perhaps I've misunderstood how this snippet works.
Is there a functional reason for naming the function both in the variable declaration and the function construct?
Is there a functional reason for naming the function both in the variable declaration and the function construct?
Yes. function bar() {} causes the function's name property to be set to bar, which can be useful for, e.g., debugging in stack traces.
Regarding some of the naming confusion you alluded to, this might help:
function bar() {}
^ This is a function declaration, as it does not exist as part of an assignment expression.
var foo = function() {};
^ This is an assignment expression where the right-hand operand is a function expression, and where the function expression defines an anonymous function.
var foo = function bar() {};
^ This is an assignment expression where the right-hand operand is a function expression, and where the function expression defines a named function.
It's probably worth noting that function declarations can be referenced locally by their function name, so the following statements are roughly equivalent:
function bar() {}
var bar = function() {};
I say roughly equivalent, because the second statement still results in an anonymous function, rather than a named function. There's also a subtle difference in how function declarations get hoisted. Consider the following, for example:
function test() {
hello();
var hello = function () { console.log('hello'); };
}
test();
// > TypeError: hello is not a function
Note that hello was technically defined where we tried to invoke it (the exception is simply that it's not a function (yet)). This is due to variable hoisting. As expected, though, we haven't yet assigned our function to the hello variable. This is easier to show than to explain, really. Basically, due to hoisting, the above test example is equivalent to:
function test() {
var hello; // declared, but not assigned yet
hello();
hello = function () { console.log('hello'); }; // now the assignment happens
}
Compare that to an actual function declaration:
function test() {
hello();
function hello() { console.log('hello'); };
}
test();
// > "hello"
Notice that even though the declaration is below the invocation command, it still works, because function declarations get hoisted as a whole to the top of their scope (in this case, test).
If that's confusing, here's a more condensed description of behavior that might help: declarations get hoisted, not assignments. As long as you understand the difference between function declarations and function expressions, that's all you need to know. :)
By writing var foo = function (){...} you are declaring a variable named foo that holds an anonymous function. By writing var foo = function bar(){...} you are declaring a variable named foo that holds a named function as bar. As #jmar777 pointed out in his answer, this is useful to follow stack traces when debugging and bug fixing.
This question already has answers here:
var functionName = function() {} vs function functionName() {}
(41 answers)
Closed 9 years ago.
What is the difference between the following lines of code?
//Function declaration
function foo() { return 5; }
//Anonymous function expression
var foo = function() { return 5; }
//Named function expression
var foo = function foo() { return 5; }
Questions:
What is a named/anonymous function expression?
What is a declared function?
How do browsers deal with these constructs differently?
What do the responses to a similar question (var functionName = function() {} vs function functionName() {}) not get exactly right?
They're actually really similar. How you call them is exactly the same.The difference lies in how the browser loads them into the execution context.
Function declarations load before any code is executed.
Function expressions load only when the interpreter reaches that line of code.
So if you try to call a function expression before it's loaded, you'll get an error! If you call a function declaration instead, it'll always work, because no code can be called until all declarations are loaded.
Example: Function Expression
alert(foo()); // ERROR! foo wasn't loaded yet
var foo = function() { return 5; }
Example: Function Declaration
alert(foo()); // Alerts 5. Declarations are loaded before any code can run.
function foo() { return 5; }
As for the second part of your question:
var foo = function foo() { return 5; } is really the same as the other two. It's just that this line of code used to cause an error in safari, though it no longer does.
Function Declaration
function foo() { ... }
Because of function hoisting, the function declared this way can be called both after and before the definition.
Function Expression
Named Function Expression
var foo = function bar() { ... }
Anonymous Function Expression
var foo = function() { ... }
foo() can be called only after creation.
Immediately-Invoked Function Expression (IIFE)
(function() { ... }());
Conclusion
Douglas Crockford recommends to use function expression in his «JavaScript: The Good Parts» book because it makes it clear that foo is a variable containing a function value.
Well, personally, I prefer to use Declaration unless there is a reason for Expression.
Regarding 3rd definition:
var foo = function foo() { return 5; }
Heres an example which shows how to use possibility of recursive call:
a = function b(i) {
if (i>10) {
return i;
}
else {
return b(++i);
}
}
console.log(a(5)); // outputs 11
console.log(a(10)); // outputs 11
console.log(a(11)); // outputs 11
console.log(a(15)); // outputs 15
Edit:
more interesting example with closures:
a = function(c) {
return function b(i){
if (i>c) {
return i;
}
return b(++i);
}
}
d = a(5);
console.log(d(3)); // outputs 6
console.log(d(8)); // outputs 8
The first statement depends on the context in which it is declared.
If it is declared in the global context it will create an implied global variable called "foo" which will be a variable which points to the function. Thus the function call "foo()" can be made anywhere in your javascript program.
If the function is created in a closure it will create an implied local variable called "foo" which you can then use to invoke the function inside the closure with "foo()"
EDIT:
I should have also said that function statements (The first one) are parsed before function expressions (The other 2). This means that if you declare the function at the bottom of your script you will still be able to use it at the top. Function expressions only get evaluated as they are hit by the executing code.
END EDIT
Statements 2 & 3 are pretty much equivalent to each other. Again if used in the global context they will create global variables and if used within a closure will create local variables. However it is worth noting that statement 3 will ignore the function name, so esentially you could call the function anything. Therefore
var foo = function foo() { return 5; }
Is the same as
var foo = function fooYou() { return 5; }
Though the complete difference is more complicated, the only difference that concerns me is when the machine creates the function object. Which in the case of declarations is before any statement is executed but after a statement body is invoked (be that the global code body or a sub-function's), and in the case of expressions is when the statement it is in gets executed. Other than that for all intents and purposes browsers treat them the same.
To help you understand, take a look at this performance test which busted an assumption I had made of internally declared functions not needing to be re-created by the machine when the outer function is invoked. Kind of a shame too as I liked writing code that way.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
JavaScript: var functionName = function() {} vs function functionName() {}
There are two possible methods for pulling out a function in Javascript:
var foo = function() { ... }
This is a bit contrived; another common pattern is:
var foo = {
baz: 43,
doSomething: function() {
// ...
}
}
versus
function foo() {
// ...
}
Is there an explicit reason to prefer one or the other?
It all comes down to preference to where you declare your functions; hoisting.
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. This means that code like this:
function foo() {
bar();
var x = 1;
}
is actually interpreted like this:
function foo() {
var x;
bar();
x = 1;
}
Notice that the assignment portion of the declarations were not hoisted. Only the name is hoisted. This is not the case with function declarations, where the entire function body will be hoisted as well.
function test() {
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { // function expression assigned to local variable 'foo'
alert("this won't run!");
}
function bar() { // function declaration, given the name 'bar'
alert("this will run!");
}
}
test();
In this case, only the function declaration has its body hoisted to the top. The name 'foo' is hoisted, but the body is left behind, to be assigned during execution.
You can give names to functions defined in function expressions, with syntax like a function declaration. This does not make it a function declaration, and the name is not brought into scope, nor is the body hoisted.
foo(); // TypeError "foo is not a function"
bar(); // valid
baz(); // TypeError "baz is not a function"
bin(); // ReferenceError "bin is not defined"
var foo = function () {}; // anonymous function expression ('foo' gets hoisted)
function bar() {}; // function declaration ('bar' and the function body get hoisted)
var baz = function bin() {}; // named function expression (only 'baz' gets hoisted)
foo(); // valid
bar(); // valid
baz(); // valid
bin(); // ReferenceError "bin is not defined"
So, if your preference is to have functions hoist to the top use a function declaration otherwise use expression. I prefer the latter as I typically build object literals with methods as function expressions.
Named function expressions can be handy when errors are thrown. The console will tell you what the function is instead of stating anonymous aka stack trace.
You've hit on a couple different things here, but I'll try to hit your main question first.
In general....
function() { ... } is a function expression. Syntaxically this is on the same level as 2 or [4,5]. This represents a value. So doing var foo=function(){ ... } will work as planned, every time.
function foo() { ... } is a function declaration. This might seem to do the same thing as var foo=function(){...}, but there's a small caveat. As its a declaration, it works similar to the concept of variable hoisting in JS (basically, all variable declarations are done before any expressions are evaluated).
A good example is from here:
function test() {
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { // function expression assigned to local variable 'foo'
alert("this won't run!");
}
function bar() { // function declaration, given the name 'bar'
alert("this will run!");
}
}
test();
Basically variable hoisting has brought the value up to the top, so this code is equivalent (in theory) to :
function test() {
var foo;//foo hoisted to top
var bar=function(){//this as well
alert("this will run!");
}
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { // function expression assigned to local variable 'foo'
alert("this won't run!");
}
}
NB: I'd like to take this spot to say that JS interpreters have a hard time following theory, so trusting them on somewhat iffy behaviour is not recommended. Here you'll find a good example at the end of a section where theory and practice end up not working (there are also some more details on the topic of expressions vs declarations).
Fun fact: wrapping function foo() {...} in parentheses transforms it from a declaration to an expression, which can lead to some weird looking code like
(function foo() { return 1; })();// 1
foo; //ReferenceError: foo is not defined
Don't do this if you don't have a reason to, please.
Summary var foo=function(){ ... } is *sorta kinda * the same as function foo(){ ... } except that the former does what you think it does where you think it should whereas the latter does weird stuff unless you wrap it in parens, but that messes up the scope, and JS interpreters allow you to do things that are considered syntax errors in the spec so you're led to believe that wrong things are in fact right, etc....
please use function expressions( var f=function(){...} ). There's no real reason not to, especially considering you're somewhat forced to do it when you're using dot syntax.
On to the second thing you touched.....
I'm not really sure what to say, it's kinda sorta completely different from everything else about this.
var foo = {
baz: 43,
doSomething:function() {
...
}
}
this is known as object literal syntax. JSON, which is based off of this syntax, is a pretty neat way of formatting data, and this syntax in JS is often used to declare new objects, with singleton objects for example(avoiding all the mess with declaring a function and using new ). It can also be used in the same way XML is used, and is preferred by all the cool kids...
Anyways, basically object literal syntax works like this:
{ name1: val1, .... namek:valk }
This expression is an object with certain values initialised on it. so doing var obj={ name1: val1, .... namek:valk } means that :
obj.name1==val1;
obj['name1']==val1;// x['y'] is the same thing as x.y
...
obj.namek==valk;
So what does this have to do with our example? Basically your expression is often used to declare singleton objects. But it can also be used to declare an object prototype, so someone can later do var newObj=Object.create(foo) , and newObj will have foo as a prototype.
Look into prototypal inheritence in detail if you want to really get how useful it is. Douglas Crockford talks about it in detail in one of his many talks).
There are few advantages to naming functions
names for meta analysis. functionInstance.name will show you the name.
Far more importantly, the name will be printed in stack traces.
names also help write self documenting or literate code.
There is a single disadvantage to named functions expressions
IE has memory leaks for NFE
There are no disadvantages to function declarations apart from less stylistic control
Your question really comprises of two parts, as you don't necessarily have to make your functions anonymous if they are assigned to a variable or property.
Named vs anonymous?
#Raynos highlights the main points clearly. The best part about named functions is that they will show themselves in a stack trace. Even in situations where functions are being assigned to variables/properties, it's a good idea to give your functions a name just to aid with debugging, however I wouldn't say anonymous functions are evil at all. They do serve a fine purpose:
Are anonymous functions a bad practice in JavaScript?
Function declaration vs function expression?
For that part of the question I would refer you to this question as it probably covers the topic in far more depth than I can
var functionName = function() {} vs function functionName() {}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
JavaScript: var functionName = function() {} vs function functionName() {}
In JavaScript, what's the purpose of defining a variable as a function? I've seen this convention before and don't fully understand it.
For example, at some point in a script, a function is called like this:
whatever();
But where I would expect to see a function named whatever, like this:
function whatever(){
}
Instead I'll see a variable called whatever that's defined as a function, like this:
var whatever = function(){
}
What's the purpose of this? Why would you do this instead of just naming the function?
Note: Please see the update at the end of the answer, declarations within blocks became valid (but quite complicated if you're not using strict mode).
Here's one reason:
var whatever;
if (some_condition) {
whatever = function() {
// Do something
};
}
else {
whatever = function() {
// Do something else
};
}
whatever();
You might see code like that in the initialization of a library that has to handle implementation differences (such as differences between web browsers, a'la IE's attachEvent vs. the standard addEventListener). You cannot do the equivalent with a function declaration:
if (some_condition) {
function whatever() { // <=== DON'T DO THIS
// Do something
}
}
else {
function whatever() { // <=== IT'S INVALID
// Do something else
}
}
whatever();
...they're not specified within control structures, so JavaScript engines are allowed to do what they want, and different engines have done different things. (Edit: Again, see note below, they're specified now.)
Separately, there's a big difference between
var whatever = function() {
// ...
};
and
function whatever() {
// ...
}
The first is a function expression, and it's evaluated when the code reaches that point in the step-by-step execution of the context (e.g., the function it's in, or the step-by-step execution of global code). It also results in an anonymous function (the variable referring to it has a name, but the function does not, which has implications for helping your tools to help you).
The second is a function declaration, and it's evaluated upon entry to the context, before any step-by-step code is executed. (Some call this "hoisting" because something further down in the source happens earlier than something higher up in the source.) The function is also given a proper name.
So consider:
function foo() {
doSomething();
doSomethingElse();
console.log("typeof bar = " + typeof bar); // Logs "function"
function bar() {
}
}
whereas
function foo() {
doSomething();
doSomethingElse();
console.log("typeof bar = " + typeof bar); // Logs "undefined"
var bar = function() {
};
}
In the first example, with the declaration, the declaration is processed before the doSomething and other stepwise code is run. In the second example, because it's an expression, it's executed as part of the stepwise code and so the function isn't defined up above (the variable is defined up above, because var is also "hoisted").
And winding up: For the moment, you can't do this in general client-side web stuff:
var bar = function foo() { // <=== Don't do this in client-side code for now
// ...
};
You should be able to do that, it's called a named function expression and it's a function expression that gives the function a proper name. But various JavaScript engines at various times have gotten it wrong, and IE continued to get very wrong indeed until very recently.
Update for ES2015+
As of ES2015 (aka "ES6"), function declarations within blocks were added to the specification.
Strict mode
In strict mode, the newly-specified behavior is simple and easy to understand: They're scoped to the block in which they occur, and are hoisted to the top of it.
So this:
"use strict";
if (Math.random() < 0.5) {
foo();
function foo() {
console.log("low");
}
} else {
foo();
function foo() {
console.log("high");
}
}
console.log(typeof foo); // undefined
(Note how the calls to the functions are above the functions within the blocks.)
...is essentially equivalent to this:
"use strict";
if (Math.random() < 0.5) {
let foo = function() {
console.log("low");
};
foo();
} else {
let foo = function() {
console.log("high");
};
foo();
}
console.log(typeof foo); // undefined
Loose mode
Loose mode behavior is much more complex and moreover in theory it varies between JavaScript engines in web browsers and JavaScript engines not in web browsers. I won't get into it here. Just don't do it. If you insist on function declarations within blocks, use strict mode, where they make sense and are consistent across environments.
this is so you can store functions in variables and e.g. pass them to other functions as parameters. One example where this is usefull is in writing asynchronous functions which are passed callbacks as arguments
var callback = function() { console.log('done', result)}
var dosomething = function(callback) {
//do some stuff here
...
result = 1;
callback(result);
}
Since functions are objects in javascript you can extend them with properties and methods as well.
Functions in JavaScript are objects; they're values, in other words. Thus you can always set a variable to refer to a function regardless of how the function is defined:
function foo() { ... }
var anotherFoo = foo;
anotherFoo(); // calls foo
Functions are values that can be used as object properties, function parameters, array elements, and anything else a general value can do in JavaScript. They're objects and can have their own properties too.
When you assign a function to a variable, you can then pass it around as an argument to other functions, and also extend it to make use of Javascript's Object model.
If you declare a functionvariable, using "var", within a function, the variable can only be accessed within that function. When you exit the function, the variable is destroyed. These variables are called local variables. You can have local variables with the same name in different functions, because each is recognized only by the function in which it is declared.
This question already has answers here:
What is this practice called in JavaScript?
(7 answers)
Closed 8 years ago.
(function() {
//do stuff
})();
EDIT: I originally thought this construct was called a closure - not that the effect that it caused results (potentially) in a closure - if variables are captured.
This is in no way to do with the behaviour of closures themselves - this I understand fully and was not what was being asked.
It is an anonymous function (or more accurately a scoped anonymous function) that gets executed immediately.
The use of one is that any variables and functions that are declared in it are scoped to that function and are therefore hidden from any global context (so you gain encapsulation and information hiding).
it's an anonymous function but it's not a closure since you have no references to the outer scope
http://www.jibbering.com/faq/notes/closures/
I usually call it something like "the immediate invocation of an anonymous function."
Or, more simply, "function self-invocation."
Kindof. It's doesn't really close around anything though, and it's called immediately, so it's really just an anonymous function.
Take this code:
function foo() {
var a = 42;
return function () {
return a;
}
}
var bar = foo();
var zab = bar();
alert(zab);
Here the function returned by foo() is a closure. It closes around the a variable. Even though a would apear to have long gone out of scope, invoking the closure by calling it still returns the value.
No, a closure is rather something along these lines:
function outer()
{
var variables_local_to_outer;
function inner()
{
// do stuff using variables_local_to_outer
}
return inner;
}
var closure = outer();
the closure retains a reference to the variables local to the function that returned it.
Edit: You can of course create a closure using anonymous functions:
var closure = (function(){
var data_private_to_the_closure;
return function() {
// do stuff with data_private_to_the_closure
}
})();