Prev: Google.com is broken in Firefox 3.6.3
Next: FAQ Topic - How do I get my browser to report javascript errors?(2010-05-08)
From: Lasse Reichstein Nielsen on 8 May 2010 13:31 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 8 May 2010 14:08 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 8 May 2010 15:13 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 8 May 2010 16:24 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 8 May 2010 18:31 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>.
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 Prev: Google.com is broken in Firefox 3.6.3 Next: FAQ Topic - How do I get my browser to report javascript errors?(2010-05-08) |