From: Lasse Reichstein Nielsen on
williamc <none(a)nowhere.net> writes:

> Question: why does 'function F(){return 3}' need the parentheses around
> it to eval to 'function' in the non-IE implementations?

Because the string passed to eval is parsed as a Program, which makes
"function F(){return 3}" be evaluated as a function declaration. The
result of the eval call is the value of the last evaluated
ExpressionStatement's expression - and since there are none, the
result is undefined.

If you add the parentheses, then "(function F(){return 3})" is parsed
as a StatementExpression containing a parenthesized
FunctionExpression.

/L
--
Lasse Reichstein Holst Nielsen
'Javascript frameworks is a disruptive technology'

From: Garrett Smith on
williamc wrote:
> On 5/7/2010 5:04 PM, Dr J R Stockton wrote:
>> The expression typeof eval("(function F(){return 3})") gives
>> "function" in Firefox and Chrome (and probably in Opera and Safari); but
>> in IE8 it gives "undefined".
>>
>> What do I need to do to get the same in IE8 as in the others, i.e. for
>> eval to return an actual executable function, which would return 3 ?
>>
>
> Question: why does 'function F(){return 3}' need the parentheses around
> it to eval to 'function' in the non-IE implementations?

It doesn't. In fact, eval('function F(){return 3}') works as specified
in Spidermonkey and in Webkit's JS engine. The different behavior you
are seeing in IE is caused by JScript interpreting an expression and
returning that value.

A FunctionDeclaration is not an Expression; it cannot return a value.

Understanding the behavior you may be seeing requires an understanding
of how the language is designed to be interpreted and how JScript
deviates from that.

When the (one) argument to eval is a string value, it is parsed as a
Program. In ES3, eval uses the calling context's scope. What that means
is that when eval is called, it can access and can create variables
using the scope chain from where it was called. An example of that.

var a = 9;
function testEval(){
var a;
// When eval is called, calling context's scope is used.
eval('a = 11');
return a;
}
alert(testEval(), a)

When `testEval` is called, a VO is created and `a` added to it with
value `undefined`. When the `eval` function is called, that VO is used
and so expression 'a = 11' resolves `a` on that VO.

The string starting with "function F(){return 3}" could be parsed only
as a FunctionDeclaration. This is because an ExpressionStatement cannot
begin with "function ".

When a FunctionDeclaration is parsed, as is the case with your example
code, it is added as a property to the VO (Variable Object).

and so the code:

eval("function F(){return 3}");

- should create a property of the calling context's scope.

And indeed it does:

eval("function F(){return 3}");
F();

FunctionDeclarations are not Expressions and so eval completes normally
and returns undefined, as can be expected.

A FunctionDeclaration is not a Statement and as such, needs not be
followed by a terminating semicolon, thus:

eval("function F(){return 3}alert(F())");

- runs, but:-

eval("(function F(){return 3})alert(F())");

- is a SyntaxError because every statements must be terminated by a
semicolon or a line terminator, in some cases, but ASI discussions
getting off topic.

What you are seeing in Microsoft JScript is that the Token is evaluated
as both an Expression and a FunctionDeclaration. When JScript sees:

eval("function F(){return 3}");

It sees a FunctionExpression. According to MS-ES3, JScript parses both a
FunctionDeclaration and a FunctionExpression. The identifier F is added
to scope. This is a well-known JScript bug.

An ExpressionStatement cannot start with the function keyword because
that might make it ambiguous with a FunctionDeclaration.

Thus:

eval("function(){return 3}");

- should result in SyntaxError.

JScript does not throw a SyntaxError there because it allows f

When the Program starts with an expression, such as:

eval("(function F(){return 3})");

- the eval function parses the Grouping Operator is an expression and
returns the value, the function F.

There is one more significant difference here: The optional identifier
in a FunctionExpression does not affect the enclosing scope. This means
that with:

eval("(function F(){return 3})");

The identifier `F` is not added to enclosing scope.

Unlike a FunctionDeclaration, which is, as was demonstrated above. Again:

eval("function F(){return 3}");

A FunctionDeclaration is parssed and identifier `F` is added to
enclosing scope with the value of that function.

So again, a FunctionDeclaration is not an Expression. And an
ExpressionStatement cannot begin with "function ".
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
From: Garrett Smith on
Lasse Reichstein Nielsen wrote:
> williamc <none(a)nowhere.net> writes:
>
[...]
> If you add the parentheses, then "(function F(){return 3})" is parsed
> as a StatementExpression containing a parenthesized
> FunctionExpression.
>

s/StatementExpression/ExpressionStatement
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
From: williamc on
On 5/8/2010 1:31 PM, Lasse Reichstein Nielsen wrote:
> williamc <none(a)nowhere.net> writes:
>
>> Question: why does 'function F(){return 3}' need the parentheses around
>> it to eval to 'function' in the non-IE implementations?
>
> Because the string passed to eval is parsed as a Program, which makes
> "function F(){return 3}" be evaluated as a function declaration. The
> result of the eval call is the value of the last evaluated
> ExpressionStatement's expression - and since there are none, the
> result is undefined.
>
> If you add the parentheses, then "(function F(){return 3})" is parsed
> as a StatementExpression containing a parenthesized
> FunctionExpression.

Ok, thanks.

From: Dr J R Stockton on
In comp.lang.javascript message <z5edIBuhBI5LFw7s(a)invalid.uk.co.demon.me
rlyn.invalid>, Fri, 7 May 2010 22:04:33, Dr J R Stockton
<reply1018(a)merlyn.demon.co.uk> posted:
>The expression typeof eval("(function F(){return 3})") gives
>"function" in Firefox and Chrome (and probably in Opera and Safari); but
>in IE8 it gives "undefined".
>
>What do I need to do to get the same in IE8 as in the others, i.e. for
>eval to return an actual executable function, which would return 3 ?

typeof eval("T=function F(){return 3}")

--
(c) John Stockton, nr London, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 7.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
MiniTrue is good for viewing/searching/altering files, at a DOS / CMD prompt;
free, DOS/Win/UNIX, new via <URL:http://www.merlyn.demon.co.uk/pc-links.htm>.