Do var fn = function() {...} and var fn = function foo() {...} ever differ? - javascript

When you're assigning a function to a variable, does it make any difference at all if you use a named instead of an anonymous function. The following generates an error that "foo() is not defined".
var fn = function foo(){...};
foo();
Can anyone clear up what's going on here?

You're creating a named function expression.
Except in IE, the name is only visible inside the function.

In your example, the variable fn is accessible in the current scope, but foo is only accessible in the functions scope. For example:
var bar = function foo() {
document.write("Internally, Foo is " + typeof foo + "<br/>");
document.write("Internally, Bar is " + typeof bar + "<br/>");
};
document.write("Foo is " + typeof foo + "<br/>");
document.write("Bar is " + typeof bar + "<br/>");
bar();
Will produce:
Foo is undefined
Bar is function
Internally, Foo is function
Internally, Bar is function
http://jsfiddle.net/robert/TEnjb/

Because it (foo) is not defined ;-)
In this context, function is a function-expression ("FunctionExpression") and not a function-statement ("FunctionDeclaration") -- there are two different productions in the grammar. Only the function-statement form [magically] assigns (and hoists the assignment) of the function name to the appropriate variable. Even functions created with a function-expression can have a name, it just happens to be optional, but there is no implicit assignment as with the other form.
[Edit: Apparently this is more quirky then I imagined. In any case, the above cases hold for a properly conforming browser. For instance Gecko has the "function statement extension, which is non-conforming, and IE/JScript exhibits different behavior, which is also non-conforming. Both of these are incorrect implementations according to the grammar specification.]
Consider the following, which should hopefully show why a ([more] conforming implementation) will sanely throw an exception:
// `function` is just an expression here -- there is no good reason for it to
// cause an implicit side-effect. And, according to the specification, it will not.
(function foo () {}).name // "foo", at least in FF
foo // undefined
On a side note: Any function production which is not a top-level statement or a statement directly inside a function block is a function-expression. The behavior of the following is quirky across browsers:
foo() // works in IE (this should never work)
if (true) {
// this is an INVALID GRAMMAR production, although it is accepted in browsers,
// with different operational semantics
function foo () {
}
}
foo() // works in FF and IE (this should never work)
Happy coding.
A little trip to the ECMAScript specification to talk about the grammar. The "rules" can be equally found there, although I find Ed. 5 to be written in the most confusing manner possible. (It misses for forest for all the trees...)
Grammar for FunctionExpression:
// There is a silly long expression tree to get here.
// Look it up if you want :)
FunctionExpression : function Identifier [optional] ( FormalParameterListopt ) { FunctionBody }
Grammar for FunctionDeclaration (what I refer to as a function-statement above), and associated "chain":
FunctionBody : SourceElements [optional]
Program : SourceElements [optional]
SourceElements : SourceElement
SourceElements SourceElement
SourceElement : Statement
FunctionDeclaration
FunctionDeclaration : function Identifier ( FormalParameterListopt ) { FunctionBody }
Note that there is no grammar rule for the "INVALID GRAMMAR" noted. The only way to get to a FunctionDeclaration is through a SourceElement which is only valid inside a FunctionBody or Program (which does not include other blocks like if). "Normal expressions", as a FunctionExpression are restricted, as per below:
An ExpressionStatement cannot start with an opening curly brace because that might make it ambiguous with a Block. Also, an ExpressionStatement cannot start with the function keyword because that might make it ambiguous with a FunctionDeclaration.
...and an apt note from the spec:
Several widely used implementations of ECMAScript are known to support the use of FunctionDeclaration as a Statement. However there are significant and irreconcilable variations among the implementations in the semantics applied to such FunctionDeclarations. Because of these irreconcilable difference, the use of a FunctionDeclaration as a Statement results in code that is not reliably portable among implementations.

Technically, fn is a function pointer pointing to "foo", but you don't really see this in Javascript. You should really just write:
function foo() {
/* ... */
}
foo();
As others have pointed out, your assignment makes the foo function "live" only in the scope of fn, so when fn goes out of scope, the function object could in principle be cleaned up. If you have a really compelling reason to do that then use the function pointer, but otherwise you can just keep the function global.

On some versions of IE this will work, but only because they are non-conforming.
var fn // declares a variable named fn
= function // initializes fn
foo // declares a name foo that is only visible within the function body.
(){
... // foo is visible here.
};
foo(); // foo is not defined here (except on IE 6 and earlier)
fn(); // works just fine.

Note also that although it's often said that:
function foo() {
};
is just syntactic sugar for:
var foo = function() {
};
it's actually not quite true.
In the former case the named function is immediately available when the script is parsed regardless of the order of definitions in the file.
In the latter, the anonymous function body is parsed immediately, but its assignment to a locally scoped variable doesn't happen until that line of code is executed. This means that you can't call foo() in any code executed before then.

Depending on the scope and how you define the function it can be a Function Declaration, Function Expression, or Function Statement. These three function types are treated and loaded differently. Among them, only function declarations require a name. So two other types can be defined without a name. These three types are also different in they way they are assigned to a variable with the function name.
Function Declaration : is defined in the top scope and is not used in another expression/statement (e.g., it is not assigned to a variable)
function foo(){}
The function object is assigned to the variable foo in the global scope.
Function Expression : is defined in another expression/statement.
var bar = function foo(){}
The function object is assigned to the variable foo but in the inner scope (i.e., the scope inside the function)
Function Statement : they are allowed to be anywhere where plain Statements are allowed.
if (true) {
function foo(){ }
}
The function object is assigned to the variable foo in the outer scope (i.e., the scope contains the function definition).
For more information look at this address: http://kangax.github.com/nfe/

Related

Does this line contain a function declaration?

The following line is known as a function expression in JavaScript. Does it contain within it a function declaration?
var foo = function() {};
Edit: edited for clarity.
No, it does not. Both function expressions and function declarations do define functions, and contain the function keyword.
How they differ is basically determined where they appear in the source code, their syntax is otherwise the same. It is
a function expression when it appears where an expression is expected, e.g. within the grouping operator or an assignment expression (as in your code)
a function declaration when it appears directly in the body of a function, module, script (global code), or eval code. Since ES6, declarations can also appear as part of a StatementList, i.e. inside a block.
a function statement when it appears where a statement is expected. Until ES6, this term was used to distinguish it from a declaration when the function syntax appeared in a block. If not inside a block, it is basically equivalent to a declaration.
Also read http://kangax.github.io/nfe/ which explain all these terms (pre-ES6 though).
For the difference between their evaluations see var functionName = function() {} vs function functionName() {}.
We can readily determine that this is not function declaration,
according to ES5 section 14:
Program :
SourceElementsopt
SourceElements :
SourceElement
SourceElements SourceElement
SourceElement :
Statement
FunctionDeclaration
A FunctionDeclaration can only be a SourceElement (a quick search for FunctionDeclaration shows no other grammatical use), and a SourceElement can only be a top-level component of a list of SourceElements (either a Program or a FunctionBody). This use of function is nested inside of an assignment, so it cannot be a top-level SourceElement.
Furthermore, we can also rule out this as a FunctionDeclaration by its definition:
FunctionDeclaration :
function Identifier ( FormalParameterListopt ) { FunctionBody }
Your code does not have an Identifier, which is mandatory for FunctionDefinitions (but optional for FunctionExpressions).
A Function Expression defines a function but does not declare a function. As such the code
var foo = function() {};
defines a function and then assigns it to a variable.
Where as
function foo() {};
defines a function and declares it without the need for an assignment.

What's the difference between naming a function (as opposed to leaving it anon) and creating a reference to it?

In a comment on another thread I started, someone said this:
#adlwalrus yes. try this: var foo = function bar(){}; console.log(foo); But be aware that bar is only function name (what does it mean I'm not sure exactly myself) and not a reference to it, so you can't call it by doing bar(). And assigning (even named function) is not the same as declaring a function. Hoisting (bumping to top of the scope) only works for declarations, assignment will stay in place. – valentinas 6 hours ago
What purpose does a function name serve if you can't call it with bar()?
For the function to call itself.
var x = function y(val){
if (val){
console.log(val);
y(val-1);
}
};
x(5);
> 3
> 2
> 1
y(3);
> ReferenceError: y is not defined
You're referring to a named function expression. The spec requires that the name of such functions only be available within the scope of the new function. Spec quote:
The Identifier in a FunctionExpression can be referenced from inside
the FunctionExpression's FunctionBody to allow the function to call
itself recursively. However, unlike in a FunctionDeclaration, the
Identifier in a FunctionExpression cannot be referenced from and does
not affect the scope enclosing the FunctionExpression.
On the other hand, the result of that expression is a reference to the new function, which can be saved and referenced anywhere.
Lots of details here:
http://kangax.github.com/nfe/#named-expr
I'd read the whole thing.
As for benefits, another is that it makes them easier to identify in a debugger.
There are two ways to create a function in JavaScript, a "function declaration" and a "function expression." I believe it was Doug Crockford who explained it best when he pointed out that unless "function" is the very first set of characters on a given line, you're performing a function expression (not a declaration).
Function declarations are finicky creatures. You'll recognize them when you see them. They look like this:
function foo() { /* ... */ }
They're always given a name (it's requited) and the name is locally scoped to the lexical context under which the function is declared. So if you perform a function declaration in the global context, then the function can be referenced via it's name globally. If you do it within a function, the function's name can be referenced only within that function and any functions declared within that function.
I think the most important aspect of this method of declaring a function (one that is rarely commented on) is that the function initialization gets hoisted to the top of the current lexical context. Therefore, you should never, ever use a function declaration within a conditional, such as this:
//DON'T DO THIS!
if (x) {
function foo() { return 1; }
} else {
function foo() { return 2; }
}
foo(); //will always be 2, regardless of the value of x.
A function expression is slightly different. Often, they're directly assigned to a variable, like so:
var foo = function() { /* ... */ };
This is nearly identical to the function declaration above except that the initialization is not hoisted. So you can do the following:
var foo;
if (x) {
foo = function() { return 1; };
} else {
foo = function() { return 2; };
}
foo(); //will be 1 or 2, depending on the truthy-ness of x.
So, back to the original question. Function expressions can also have a name, though it's not required and it's not scoped to the context in which the function is declared (as with function declarations). Instead, it gets scoped to the function's own lexical context. This is very useful in some cases. My personal favorite is this pattern:
(function foo() {
//Do something.
setTimeout(foo, 1000);
}());
foo; //undefined
Because of the parenthesis before the word "function", this is a function expression and the name is scoped internally only. But that's okay, because we only need to call it internally (via setTimeout()). The result is that the function will execute once immediately, then will re-execute every second or so after it's finishes execution. This is safer than using setInterval() because it will wait until it's done executing before rescheduling itself, preventing overlaps that could cause missed executions and/or "domination" of the JavaScript thread.
Essentially, the use of a named function expression is limited, but when you need it, it's very powerful.

Are named functions preferred over anonymous functions in JavaScript? [duplicate]

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() {}

whats the difference between function foo(){} and foo = function(){}? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
JavaScript: var functionName = function() {} vs function functionName() {}
are they the same? I've always wondered
No, they're not the same, although they do both result in a function you can call via the symbol foo. One is a function declaration, the other is a function expression. They are evaluated at different times, have different effects on the scope in which they're defined, and are legal in different places.
Quoting my answer to this other question here (edited a bit for relevance), in case the other question were ever removed for some reason (and to save people following the link):
JavaScript has two different but related things: Function declarations, and function expressions. There are marked differences between them:
This is a function declaration:
function foo() {
// ...
}
Function declarations are evaluated upon entry into the enclosing scope, before any step-by-step code is executed. The function's name (foo) is added to the enclosing scope (technically, the variable object for the execution context the function is defined in).
This is a function expression (specifically, an anonymous one, like your quoted code):
var foo = function() {
// ...
};
Function expressions are evaluated as part of the step-by-step code, at the point where they appear (just like any other expression). That one creates a function with no name, which it assigns to the foo variable.
Function expressions can also be named rather than anonymous. A named one looks like this:
var x = function foo() { // Valid, but don't do it; see details below
// ...
};
A named function expression should be valid, according to the spec. It should create a function with the name foo, but not put foo in the enclosing scope, and then assign that function to the x variable (all of this happening when the expression is encountered in the step-by-step code). When I say it shouldn't put foo in the enclosing scope, I mean exactly that:
var x = function foo() {
alert(typeof foo); // alerts "function" (in compliant implementations)
};
alert(typeof foo); // alerts "undefined" (in compliant implementations)
Note how that's different from the way function declarations work (where the function's name is added to the enclosing scope).
Named function expressions work on compliant implementations, but there used to be several bugs in implementations in the wild, most especially Internet Explorer 8 and earlier (and some early versions of Safari). IE8 processes a named function expresssion twice: First as a function declaration (upon entry into the execution context), and then later as a function expression, generating two distinct functions in the process. (Really.)
More here: Double take and here: Named function expressions demystified
NOTE: The below was written in 2011. In 2015, function declarations in control blocks were added to the language as part of ECMAScript 2015. Their semantics vary depending on whether you're in strict or loose mode, and in loose mode if the environment is a web browser. And of course, on whether the environment you're using has correct support for the ES2015 definition for them. (To my surprise, as of this writing in July 2017, Babel doesn't correctly transpile them, either.) Consequently, you can only reliably use function declarations within control-flow structures in specific situations, so it's still probably best, for now, to use function expressions instead.
And finally, another difference between them is where they're legal. A function expression can appear anywhere an expression can appear (which is virtually anywhere). A function declaration can only appear at the top level of its enclosing scope, outside of any control-flow statements. So for instance, this is valid:
function bar(x) {
var foo;
if (x) {
foo = function() { // Function expression...
// Do X
};
}
else {
foo = function() { // ...and therefore legal
// Do Y
};
}
foo();
}
...but this is not, and does not do what it looks like it does on most implementations:
function bar(x) {
if (x) {
function foo() { // Function declaration -- INVALID
// Do X
}
}
else {
function foo() { // INVALID
// Do Y
}
}
foo();
}
And it makes perfect sense: Since the foo function declarations are evaluated upon entry into the bar function, before any step-by-step code is executed, the interpreter has no idea which foo to evaluate. This isn't a problem for expressions since they're done during the control-flow.
Since the syntax is invalid, implementations are free to do what they want. I've never met one that did what I would have expected, which is to throw a syntax error and fail. Instead, nearly all of them just ignore the control flow statements and do what they should do if there are two foo function declarations at the top level (which is use the second one; that's in the spec). So only the second foo is used. Firefox's SpiderMonkey is the standout, it seems to (effectively) convert them into expressions, and so which it uses depends on the value of x. Live example.
I got an excellent explanation on this while asking very similar question: Two functions with the same name in JavaScript - how can this work?

A simple question about Javascript functions, differences in invocation/definition

Can someone please explain the difference between the following function definitions?
var alertMessage = function alertMessage(message) {
alert(message);
}
var alertMessage = function(message) {
alert(message);
}
What are the implications of each? Thanks!
Both are function expressions, basically the difference is that the first is named, and the second one is anonymous.
For example:
var test = function test(message) {
alert(message);
};
var test1 = function(message) {
alert(message);
};
test.name; // "test"
test1.name // "" or "anonymous"
Note: The name property of function objects exist on some implementations, but it's non-standard.
Also, the name of function expressions it's useful for debugging, as you can inspect the call stack to see where you are.
This identifier is only accessible from inside the FunctionBody itself:
(function foo(){
typeof foo; // "function"
})();
typeof foo; // "undefined"
However there is a bug on the JScript implementation (in all versions of IE), which this name is leaked to its enclosing scope.
Both definitions are function expressions, as opposed to function declarations, or functions created by the Function constructor. They both assign a function to the variable alertMessage. The difference is that the first function is named, while the second is anonymous.
Named functions are usually used in function declarations, eg
function alertMessage(message) { ... }
In that case, the function declaration creates a variable in the current scope called alertMessage that references that function. Function declarations are hoisted to the top of the current scope, so you can call declared functions before they're defined in you js file.
A named function used in a function expression (such as the original question) does not create this variable, or get hoisted to the top of the execution scope, so by convention most function expressions are anonymous. The only benefits to naming a function expression are that the name variable is bound within the function (although as CMS mentions, this is implementation dependent) and the function name is output from the function's toString method. This can be useful during debugging (rather than having Firebug output (?) for a huge list of anonymous function calls).
Much more detail at MDC

Categories