Function hoisting

# Neil Mix (17 years ago)

On Jul 19, 2008, at 12:25 AM, Brendan Eich wrote:

  • ES3.1 and ES4 will both allow ‘function’ inside control flow
    statements [directly inside an explicit block, not as the lone
    unbraced consequent statement of an if, while, etc. /be], and it
    will be hoisted to the top of the block and initialized on block
    entry (to be compatible with how functions behave in ES3)

What's the behavior of an if/else control flow statement that contains
a function definition in each explicit block?

if (true) { function x() { return 1; } } else { function x() { return 2; } }

# Brendan Eich (17 years ago)

On Jul 19, 2008, at 7:20 AM, Neil Mix wrote:

On Jul 19, 2008, at 12:25 AM, Brendan Eich wrote:

  • ES3.1 and ES4 will both allow ‘function’ inside control flow statements [directly inside an explicit block, not as the lone unbraced consequent statement of an if, while, etc. /be], and it will be hoisted to the top of the block and initialized on block entry (to be compatible with how functions behave in ES3)

What's the behavior of an if/else control flow statement that contains a function definition in each explicit block?

if (true) { function x() { return 1; } } else { function x() { return 2; } }

Block scope -- an x in each branch's block. This avoids capturing
problems. To make a binding that extends beyond either block one just
uses let or var in an outer scope, and assigns. Richard Cornford made
this point in a different context last week (about memoizing top
level functions via var, not by overwriting a function definition).

# Brendan Eich (17 years ago)

On Jul 19, 2008, at 9:51 AM, Brendan Eich wrote:

if (true) { function x() { return 1; } } else { function x() { return 2; } }

Block scope -- an x in each branch's block. This avoids capturing problems. To make a binding that extends beyond either block one just uses let or var in an outer scope, and assigns. Richard Cornford made this point in a different context last week (about memoizing top level functions via var, not by overwriting a function definition).

Note also how this neatly separates duties with respect to const vs.
var/let. If you want a const binding to the function that survives
the end of block, you can do it in ES4, where const is assign-once:

const x; if (truthy) { x = function () 1; } else { x = function () 2; } // use x here

There is no free lunch, though. A typed function would probably want
the signature restated as an annotation on the const. And of course
if you want the function to have an intrinsic name, you'll need named
function expressions above, which may redundantly restate "x" as the
name of the function (as well as of the binding).