JavaScript函数x(){..}在`if';在Firefox中,而不是在Chrome和Opera中
考虑以下JavaScript代码:JavaScript函数x(){..}在`if';在Firefox中,而不是在Chrome和Opera中,javascript,firefox,Javascript,Firefox,考虑以下JavaScript代码: (function(){ foo(); function foo(){ alert('Hello, World!'); } })(); 在Firefox、Opera和Chrome中,这与预期一样;我们接到警报。相比之下: (function(){ if (true){ foo(); function foo(){ alert('Hello, World!'); } } })(); Firefox3.6和4(beta版)(即两
(function(){
foo();
function foo(){ alert('Hello, World!'); }
})();
在Firefox、Opera和Chrome中,这与预期一样;我们接到警报。相比之下:
(function(){
if (true){
foo();
function foo(){ alert('Hello, World!'); }
}
})();
Firefox3.6和4(beta版)(即两者都使用SpiderMonkey)抛出一个异常:未定义foo
Chrome(即V8)和Opera(即Opera使用的任何引擎)按预期(由我)工作
哪一种行为是正确的,还是由实现来决定
FWIW,再次将其封装在函数中,再次使用FF很好:
(function(){
if (true){
(function(){
foo();
function foo(){ alert('Hello, World!'); }
})();
}
})();
这是由于不同的浏览器使用不同的symantec解析。通常对第一个声明进行求值。因为if条件封装了foo方法的声明,所以不解析它。理想情况下,您不应该创建运行时条件方法 foo在执行if语句之前不会被解析,甚至在定义它之前调用它的if语句中也是如此。虽然正如您所说,它在Chrome等浏览器中工作。如果我编写这样的代码,我会期望FF表现出的行为
出于可维护性的考虑,我希望您不要这样编写代码-这是一个混乱的局面。为了安全起见,请以以下方式编写代码: var foo=function(){alert('Hello,World!');} foo() 在(function(){})()块内,您将获得真正的私有方法。根据,
SourceElement
被定义为:
SourceElement :
Statement
FunctionDeclaration
因此,FunctionDeclaration
s和Statement
s是不同的。和块(例如,if
)只能包含语句
s:
Block :
{ StatementList opt }
StatementList :
Statement
StatementList Statement
因此,根据规范,在if
s中没有函数声明。ECMA-262第3版和第5版第16节允许这样做。行为似乎由实现来决定
非标准FunctionStatement
示例:
try {
function Fze(b,a){return b.unselectable=a}
/*...*/
} catch(e) { _DumpException(e) }
函数表达式的示例
:
var Fze;
try {
Fze = function(b,a){return b.unselectable=a};
/*...*/
} catch(e) { _DumpException(e) }
function aa(b,a){return b.unselectable=a}
函数声明的示例
:
var Fze;
try {
Fze = function(b,a){return b.unselectable=a};
/*...*/
} catch(e) { _DumpException(e) }
function aa(b,a){return b.unselectable=a}
我想你会在这里找到答案:谢谢你,菲利克斯。这让我想到了这里:请看,这是正确的:所有浏览器都实现了自己对ECMAScript标准的扩展,以处理块中的函数声明。