1

Consider two styles of javascript function declarations (out of four, I think):

function foo() {
    // ...
}

versus

var foo = function() {
    // ...
}

In many circumstances these will behave the same, and I think I grok the main difference as explained in e.g. these SO questions:

difference-between-var-foo-function-and-function-foo

usual-functions-vs-function-variables-in-javascript

which both have answers linking to this very helpful explanation:

javascript-function-declaration-ambiguity

But I would like to combine both styles in one statement; one short/minifiable local variable name (because I will need to refer to it quite often) and one descriptive name (I want to get something friendly out of .name).

This is where I get confused. It is as if the act of immediately assigning the function to a variable leaves it undefined under its own name:

var f = function foo() {
    // ...
};
console.log( f.name );   // "foo"
console.log( foo.name ); // !? error: foo is not defined ?!

So to get to the question: why does this not work? Or, more likely, what might I still be misunderstanding about these two declaration styles?

Note, that the following does not result in an error:

var f = foo;
function foo() {
    // ...
}
console.log( f.name );   // "foo"
console.log( foo.name ); // "foo"

How, exactly, is this different?

PS: I think this is different from this SO question:

in-javascript-what-is-the-motivation-or-advantage-of-using-var-foo-function-f...

which is about a special case of my predicament, where the variable name and function name are the same, i.e.

var foo = function foo() {
    // ...
};
Community
  • 1
  • 1
Rad Haring
  • 905
  • 7
  • 7

2 Answers2

1

When you write

var f = function foo () { ... }

the scope of foo is just the body of the function, not the enclosing function. This is mainly useful for creating anonymous recursive functions.

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

recommends against using that notation, because they don't work correctly in some implementations.

Community
  • 1
  • 1
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Well that was quick, thanks! So are you saying that the scope of a function's "proper" name is different when it occurs as rvalue in an assignment rather than as a separate statement (see the working snippet below the one with the error) – Rad Haring Oct 03 '13 at 22:07
  • It's the difference between a function expression and a function statement. – Barmar Oct 03 '13 at 22:09
  • Which, by spec, have different effects on the enclosing scope. The answer in your link was helpful, thanks again... I should probably have searched more extensively. – Rad Haring Oct 03 '13 at 22:15
1

This is how I see it. Every function in javascript inherits from Function object and Function object has property .name.

this creates the function object with the name foo in the global space:

function foo(){}

this creates local anonymous(thus no name) function and assigns is to the variable f which lives in global space:

var f = function(){}

this creates the function object and assigns it to variable, it doesn't exist in global context, only local to f, the same as above, but assigns the name foo:

var f = function foo(){}

edit: for better picture consider following

(function foo(){console.log("executing foo")})();
(function(){console.log("executing anonymous")})();

are both function(objects) in global context - first with name, second without name. If they are created in variable it works the same just context is different.

webduvet
  • 4,220
  • 2
  • 28
  • 39