0

Javascript has this funny thing called function hoisting, which means we can use a function expression before (that is, visually) it is declared (caution: my wording may be incorrect, feel free to comment on it).

fn1(); // works OK
function fn1() {console.log('fn1');}

However, if we pass a named function as an argument, function hoisting does not happen. The syntax seems very similar but I suppose this is not a function expression anymore but a named anonymous function (!).

fn2(); // throws a ReferenceError as fn2 is not defined
setTimeout(function fn2() {console.log('fn2')}, 0);
  • Is it indeed a difference between a function expression and a named lambda ?
  • Are there other notable differences between the two ?
  • Considering fn2 is a named lambda, is the fn2 name accessible from anywhere else than in fn2 itself ?
Greg
  • 2,600
  • 3
  • 16
  • 20
  • @Sean I don't think that's the same question: I'm not using `var` in any case and my function is named in both cases. I use the exact same syntax unlike on that question. – Greg Nov 05 '14 at 02:23
  • 1
    That's the thing, you *don't* use the exact same syntax. The first case is a "function declaration" (`syntax A`, if you will) while the second case is a "named function expression" (`syntax B`). These two different syntaxes for declaring a function have different behaviors, as discussed in the suggested duplicate question and in the article I linked to in my first comment. – Sean Vieira Nov 05 '14 at 02:28
  • 1
    The "named function expression", by the by, is just a normal function expression. The *only* specced difference between a "named" an "anonymous" function expression (that I am aware of) is that the name of the named expression is available in the function's scope. – Sean Vieira Nov 05 '14 at 02:31
  • OK - what threw me off is that those syntaxes look similar, as opposed to the `var f = ...` writing that is more easily differentiated. Thanks for your comments and pointing to the correct wording – Greg Nov 05 '14 at 02:43
  • "*Javascript has this funny thing called function hoisting*" no, it doesn't. I has a very sensible thing of parsing code and initialising variables before doing execution. Variables and functions are created first, then execution begins. Assignments happen in the execution phase. – RobG Nov 05 '14 at 02:48
  • @RobG funny doesn't necessarily exclude sensible ;) – Greg Nov 05 '14 at 02:57
  • @Greg—sure, but the term "hoisting" infers behaviour that doesn't happen. This is one of those things that, to me at least, is easier to understand from first principles rather than jargon. Function expressions aren't declarations, they are processed during execution. ;-) – RobG Nov 05 '14 at 03:02

2 Answers2

1

Only function statements/declarations should bind a corresponding variable (and are subject to hoisting).

A function inside the argument list to setTimeout is treated as a function expression; it has a name ("fn2") but is not bound to the variable fn2 and is not created prior the expression being evaluated..

user2864740
  • 54,112
  • 10
  • 112
  • 187
  • by 'ideally', do you mean it is bound to the variable fn2 on some JS engines ? – Greg Nov 05 '14 at 02:25
  • @Greg I've edited that out. A long time ago in IE, function expressions that looked like function declarations (eg. were inside an 'if') would be treated as function declarations. On reflection I do not believe this ever affected function expressions in an expression context. – user2864740 Nov 05 '14 at 02:27
  • 1
    Function statements aren't supported in most browsers and aren't "hoisted" in those that do. They are also not allowed in strict mode. – RobG Nov 05 '14 at 02:50
  • @RobG good point. I've never seen those used anywhere. That's for the best apparently. – Greg Nov 05 '14 at 02:56
1

Considering fn2 is a named lambda, is the fn2 name accessible from anywhere else than in fn2 itself ?

In buggy versions of IE, yes. Named function expressions are created as variables in the enclosing execution context (which is inconsistent with ECMA-262). See Named function expressions demystified.

RobG
  • 124,520
  • 28
  • 153
  • 188