Firefox 对规范判断语句块内的函数声明的处理与其它浏览器有出入

标准参照

函数声明与函数表达式

概念一个函数有些许种途径:函数声明和函数表达式。

函数声明:
function Identifier ( FormalParameterList

opt

 ) { FunctionBody }

函数表达式:
function Identifier

opt

 ( FormalParameterList

opt

 ) { FunctionBody }

ECMAScript 根据上下和来区分函数声明和函数表达式,假设 “function
test(){}”
是一个表达式的平等组成部分,它就是是一个函数表达式,否则其就是一个函数声明。

关于函数声明和函数表达式的双重多信息,请参考 ECMAScript
规范
13 Function Definition 中的情。

函数声明可以出现的职

因 ECMAScript 规范第 13 章 Function Definition 和第 14 章 Program
中之描述,函数声明仅仅会冒出于 Program(程序,即全局环境)或函数体内。

易句话说,函数声明勿可知起在( 如 if、while 或 for 语句)中。

题材讲述

Firefox 的 TraceMonkey 引擎对函数声明的拍卖同 ECMAScript
规范的渴求不符,TraceMonkey
将片被的函数声明作为“函数语句”来处理。而别浏览器的发动机仍将马上类似片被的函数声明当作该块之外的函数声明来分析。

导致的熏陶

本着片语句被之函数声明的拍卖差异,将造成某些意义未可知随预期实现,甚至代码出错。

受影响之浏览器

Firefox  

题目分析

TraceMonkey
将片被的函数声明作为“函数语句”来处理。而任何浏览器的发动机仍拿即时类似片被之函数声明当作该块之外的函数声明来分析。

剖析以下代码:

function foo(){
  if(window===parent){
    function bar(){alert(1);}
  }
  else{
    function bar(){alert(2);}
  }
  bar();
}
foo();

以上代码中,两独标识符相同之函数声明被在了 if…else…
片被。这不符合规范的预定,但各级引擎的拍卖措施并不相同。

TraceMonkey
将这种身处块内的函数声明解析为“函数语句”,因此只会为实践到之死“函数语句”会收效,而另浏览器虽然拿两端仍当当前作用域的函数声明,即无论
if…else… 的谁分支最终见面吃实施,后者始终会覆盖前者,作为函数体 foo
内的、标识符为 foo 的函数存在。

流动:Firefox 中在 if…else… 中使函数声明的辨析方法,在 MDC
中为有叙,参见:Conditionally defining a
function

一经以上代码的论断标准 window===parent 为
true,各浏览器下之出口结果,如下表所示:

Firefox 其他浏览器
1 2

ECMAScript 规范第 5 版 12 章中之 Note
部分涉及,虽然有点实现好以函数声明作为语句处理,但这是不提倡的。

横流:本文部分内容参考了文章:取名函数表达式探秘
中的情。

化解方案

将规范语句被的函数声明替换为函数表达式,如:

function foo(){
  if(window===parent){
    var bar=function(){alert(1);}
  }
  else{
    var bar=function(){alert(2);}
  }
  bar();
}
foo();

参见

知识库

相关问题

测试环境

操作系统版本: Windows 7 Ultimate build 7600
浏览器版本: IE6
IE7
IE8
Firefox 3.6
Chrome 4.0.302.3 dev
Safari 4.0.4
Opera 10.51
测试页面:
本文更新时间: 2010-07-09

关键字

函数声明 函数表达式 语句块 同名函数 Conditionally defining a function

转载

http://w3help.org/zh-cn/causes/SJ9002