开发者

JavaScript function x(){..} treated as var x=function(){..} inside `if' in Firefox, not in Chrome and Opera

Consider the following JavaScript code:

(function(){
  foo();
  function foo(){ alert('Hello, World!'); }
})();

In Firefox, Opera and Chrome, this behaves as expected; we get an alert. Now in contrast:

(function(){
  if (true){
    foo();
    function foo(){ alert('Hello, World!'); }
  }
})();

Firefox 3.6 and 4 (beta) (i.e. SpiderMonkey for both) throws an exception: foo is not defined

Chrome (i.e. V8) and Opera (i.e. whatever engine Opera uses) work as expected (by me).

Which is the correct behaviour, or is this left to implementations to decide?

FWIW, wrap it up in a function again and it's good to go in FF again:

(function(){
  i开发者_高级运维f (true){
    (function(){
      foo();
      function foo(){ alert('Hello, World!'); }
    })();
  }
})();


According to the ECMA-262 5th Edition spec, SourceElement is defined to be:

SourceElement :
Statement 
FunctionDeclaration

So, FunctionDeclarations and Statements are different. And blocks (e.g. if) can only contain Statements:

Block :
   { StatementList opt }

StatementList :
   Statement
   StatementList  Statement

So, no FunctionDeclarations in ifs, grammatically, according to the spec. However, according to the comp.lang.javascript FAQ, Mozzila browsers and others implement a "function statement". This is allowed under section 16 of ECMA-262, Editions 3 and 5. Spidermonkey adds FunctionStatement. JScript adds FunctionDeclaration, however, JScript also has JScriptFunction. It appears the behaviour is left to implementations to decide.

Example of nonstandard FunctionStatement:

try {
  function Fze(b,a){return b.unselectable=a}
  /*...*/
} catch(e) { _DumpException(e) }

Example of FunctionExpression:

var Fze;
try {
  Fze = function(b,a){return b.unselectable=a};
  /*...*/
} catch(e) { _DumpException(e) }

Example of FunctionDeclaration:

function aa(b,a){return b.unselectable=a}


This is due to different parsing symantec different browsers are using. Usually first declaration is evaluated. Since if condition encapsulate the declaration of foo method, it is not parsed. Ideally you should not create runtime conditional methods.


foo isn't parsed until the if statement is executed - And even within the if statement you're calling it before defining it. Although as you've said it works in Chrome etc. I would expect the behavior that FF exhibits if I was writing code like that.

I hope for the sake of maintainability you're not writing code like this - That's a confusing mess.


To be on a safe side write code this way:

var foo = function() { alert('Hello, World!'); } foo();

inside (function(){ })() block you'll get true private methods.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜