Function declarations as statements

# Michael Day (15 years ago)

In ECMAScript, function declarations are SourceElements, but not Statements. This means that they can only occur at the top level, and may not be nested inside a block.

However, browsers support function declarations as statements, and many scripts on the web seem to make use of this ability, especially after they have been minified.

Is there a spec anywhere for how functions as statements should behave?

Can they be rewritten to var + function expression, so that this:

{ function f() { return 17 } }

becomes this:

{ var f = function() { return 17 } }

When implementing non-standard features, it would be nice to do so in a standard manner :)

Best ,

Michael

# Brendan Eich (15 years ago)

A recurring topic. See:

esdiscuss/2007-March/003964, esdiscuss/2008-February/005314, esdiscuss/2008-July/006812

and probably many others.

There's no common semantics among top five browsers (although IIRC three follow IE, the #2 by market share did something different long, long ago).

So for Harmony, we are reclaiming function in block (must be a direct child of a braced block) to bind a block-local name on block entry (so hoisting lives, but only to top of block -- so you can't emulate with var f = function ...).

# Allen Wirfs-Brock (15 years ago)
# Michael Day (15 years ago)

and Allen,

Thanks for the pointers.

So for Harmony, we are reclaiming function in block (must be a direct child of a braced block) to bind a block-local name on block entry (so hoisting lives, but only to top of block -- so you can't emulate with var f = function ...).

If we implemented this behaviour now, I think that would be sufficient to make JQuery and Raphaël work. Here is an example from JQuery that is giving us trouble:

if (condition) { var val, props, ... ;

 function getWH() { ... this is the function ... }

 if ( elem.offsetWidth !== 0 ) {
     getWH();
 } else {
     jQuery.swap( elem, props, getWH );
 }

 return Math.max(0, Math.round(val));

}

The getWH() function is declared in the block and only used in the block, so if we hoisted the definition to the top of the block there would not be any problems with this usage.

Best ,

Michael

# Allen Wirfs-Brock (15 years ago)

I believe that would be interoperable as long as each such function is only declared and used within a single block. Multiple declarations with the same function name in separate blocks wouldn't be interoperable among all browsers.

# Mark S. Miller (15 years ago)

On Thu, Nov 11, 2010 at 5:10 PM, Allen Wirfs-Brock < Allen.Wirfs-Brock at microsoft.com> wrote:

I believe that would be interoperable as long as each such function is only declared and used within a single block. Multiple declarations with the same function name in separate blocks wouldn't be interoperable among all browsers.

Not quite. It will be incompatible with ES5/strict on those ES5 implementations that follow < conventions:no_non_standard_strict_decls

.

For the example code you show under the assumptions you state, if you move the function declaration into the top level of the containing function or program, then it will be compat with ES5/strict best practice as well, and still with everything else.

# Garrett Smith (15 years ago)

On 11/11/10, Michael Day <mikeday at yeslogic.com> wrote:

Hi Brendan and Allen,

Thanks for the pointers.

So for Harmony, we are reclaiming function in block (must be a direct child of a braced block) to bind a block-local name on block entry (so hoisting lives, but only to top of block -- so you can't emulate with var f = function ...).

If we implemented this behaviour now, I think that would be sufficient to make JQuery

Arrogant bunch of lackeys.

and Raphaël work. Here is an example from JQuery that is

giving us trouble:

I am now reminded of the logo Allen proposed for ECMAScript.

if (condition) { var val, props, ... ;

 function getWH() { ... this is the function ... }

bugs.jquery.com/ticket/6788

I've told them about this sort of problem and they just delete the comments.

| GarrettS commented on jquery/jquery August 26, 2010 | | The comment has since been removed. | | GarrettS commented on jquery/jquery August 26, 2010 | | The comment has since been removed.

More reasons why I do not want to have anything to do with javascript.

Garrett

# Mark S. Miller (15 years ago)

On Thu, Nov 11, 2010 at 5:37 PM, Garrett Smith <dhtmlkitchen at gmail.com>wrote:

On 11/11/10, Michael Day <mikeday at yeslogic.com> wrote:

Hi Brendan and Allen,

Thanks for the pointers.

So for Harmony, we are reclaiming function in block (must be a direct child of a braced block) to bind a block-local name on block entry (so hoisting lives, but only to top of block -- so you can't emulate with var

f = function ...).

If we implemented this behaviour now, I think that would be sufficient to make JQuery

Arrogant bunch of lackeys.

and Raphaël work. Here is an example from JQuery that is

giving us trouble:

I am now reminded of the logo Allen proposed for ECMAScript.

if (condition) { var val, props, ... ;

 function getWH() { ... this is the function ... }

bugs.jquery.com/ticket/6788

I've told them about this sort of problem and they just delete the comments.

| GarrettS commented on jquery/jquery August 26, 2010 | | The comment has since been removed. | | GarrettS commented on jquery/jquery August 26, 2010 | | The comment has since been removed.

More reasons why I do not want to have anything to do with javascript.

bugs.jquery.com/ticket/6788#comment:2

If it sticks, please reconsider ;). Thanks.