Function definition inside 'if' statement

H

Henk van Winkoop

Hello,

I debugged some html file and found this:

------------------------------------------------------------
<script language="JavaScript">

if ( some_statement ) {

function MyFunction ( some_argument ) {

some_function_statements;

}

}

</script>
------------------------------------------------------------

Is it allowed to define a function INSIDE some 'if' statement?

Thanks

Henk
 
B

Baconbutty

I believe it is, but this is a subtle area, where different Javascript
engines treat it differently.

In JScript the function will be created, even if the "if" statement
does not apply. I.e. when running a function, it looks for all the
declared sub functions, and creates them.

In Firefox, the function may only be created when the "if" statement
applies.
 
N

Nigel Greenwood

Henk said:
if ( some_statement ) {

function MyFunction ( some_argument ) {

some_function_statements;

}

}
Is it allowed to define a function INSIDE some 'if' statement?

Looks like pretty poor programming to me. Why not have a single
function, with variable parameters inside the "if" loop?

Nigel
 
M

Michael Winter

On 19/10/2005 10:24, Henk van Winkoop wrote:

[snip]
<script language="JavaScript">

The language attribute has long been deprecated in favour of the
required type attribute:

if ( some_statement ) {

function MyFunction ( some_argument ) {

some_function_statements;

}

}
[snip]

Is it allowed to define a function INSIDE some 'if' statement?

Not as a function declaration. However, a function expression can be
used to conditionally create a function object.

There was a recent thread on this topic.

Subject: <variable>=function(){...}
Date: 2005/10/13 20:17 GMT
Message ID: [email protected]

<URL:http://groups.google.co.uk/group/co...read/thread/e8865df4f3a89f02/22e5fab87e8d2175>

Mike
 
B

Baconbutty

Michael Winter wrote:-
Not as a function declaration.

This works fine for me in JScript (whether "a" is undefined or not),
although admittedly I have not checked the formal grammar in the ECMA
standard, or tested in Firefox..

function f1(a)
{
if (a){
function f2(){}
}

alert(f2);
}

f1();
 
M

Michael Winter

On 19/10/2005 11:23, Baconbutty wrote:

[Placing function declarations within block statements]
This works fine for me in JScript [...]

That depends on what you define as 'working'. With a conforming
implementation, a syntax error exception would be thrown. That certainly
doesn't happen in most browsers (as I wrote in the other thread I
mentioned).
although admittedly I have not checked the formal grammar in the ECMA
standard,

It's illegal. I misremembered the precise details at the time of the
other thread (thanks again, David), but a function declaration is only
permitted within the SourceElement production. This is available at
'global' scope (within the Program production) or in the body of a
function (FunctionBody). So,

function myFunction() {}

and

function myOuterFunction() {
function myInnerFunction() {
}
}

are both legal, but nothing else is.

Function expressions enter the grammar in the MemberExpression
production, so they may appear in expressions and expression statements.
However, expression statements may not begin with either the 'function'
or '{' tokens (this is what I forgot), so

if(...) {
function() {
}
}

cannot be considered a legal function expression.
or tested in Firefox..

This is where things get interesting. Consider:

if('function' == typeof myFunction) {alert('before');}
if(true) {
function myFunction() {}
}
if('function' == typeof myFunction) {alert('after');}

In IE, both dialogs boxes are shown, so one can only assume that the
'function' token is used to create a function declaration, therefore the
resulting function object is parsed before execution, and available
before the definition is encountered.

In Fx, only the second dialog box is shown, indicating that not only is
the function conditional (a function expression), but that the
identifier - which should only be available to the function expression,
itself - is leaked into the global object, as well.

This can be confirmed by changing the if statement condition to false,
and witnessing the same behaviour in IE, but nothing in Fx.

The leaking behaviour, mentioned above, is equally odd. In IE, it always
appears to leak the identifier when presented with code like:

var global = function local() {};

However, Fx doesn't, even though it did with the previous case.

With all of this conflicting behaviour, the only sensible course of
action is to avoid doing any of this (which is why I'm not going to test
in other browsers).

Mike
 
B

Baconbutty

Michael said:
That depends on what you define as 'working'. With a conforming
implementation, a syntax error exception would be thrown. That certainly
doesn't happen in most browsers (as I wrote in the other thread I
mentioned).

Fair point. Loose language.
It's illegal. I misremembered the precise details at the time of the
other thread (thanks again, David), but a function declaration is only
permitted within the SourceElement production.

I understand precisely.
However, expression statements may not begin with either the 'function'
or '{' tokens (this is what I forgot),

Presumably so as not to create ambiguity with a Block production or a
FunctionDeclaration production.
In IE, both dialogs boxes are shown, so one can only assume that the
'function' token is used to create a function declaration, therefore the
resulting function object is parsed before execution, and available
before the definition is encountered.

In Fx, only the second dialog box is shown, indicating that not only is
the function conditional (a function expression), but that the
identifier - which should only be available to the function expression,
itself - is leaked into the global object, as well.

This can be confirmed by changing the if statement condition to false,
and witnessing the same behaviour in IE, but nothing in Fx.

The leaking behaviour, mentioned above, is equally odd. In IE, it always
appears to leak the identifier when presented with code like:

var global = function local() {};

However, Fx doesn't, even though it did with the previous case.

I understand.

IE's parser seems to treat anything in the form "function Identifier()"
as a FunctionDeclaration, in whatever grammar context.

Firefox seems to treat a FunctionDeclarations like a Statement.
With all of this conflicting behaviour, the only sensible course of
action is to avoid doing any of this (which is why I'm not going to test
in other browsers).

And presumably it would be a rare and unusual situation where you would
want to conditionally declare a function instead of using a legal
function expression for the purpose.
 
M

Michael Winter

On 19/10/2005 12:34, Michael Winter wrote:

[snip]
I misremembered the precise details at the time of the other thread
(thanks again, David),
^^^^^
Gaahh! My sincere apologies, Duncan. :(

[snip]

Mike
 
M

Michael Winter

On 19/10/2005 13:05, Baconbutty wrote:

[snip]
And presumably it would be a rare and unusual situation where you would
want to conditionally declare a function instead of using a legal
function expression for the purpose.

Absolutely. If conditional creation of a function was the goal, then the
condition would have to be reached and evaluated before the result could
be obtained. As such, it wouldn't matter how that function object was
defined: other parts of the program couldn't use it until after the
condition, so one may as well use a legal production.

Mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top