标准参考

函数声明和函数表达式

定义一个函数有两种途径:函数声明和函数表达式。

函数声明:
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

Firefox 对条件判断语句块内的函数声明的处理与其他浏览器有差异的更多相关文章

  1. 前端笔记知识点整合之JavaScript(三)关于条件判断语句、循环语句那点事

      一.条件分支语句 条件分支语句,也叫作条件判断语句,就是根据某种条件执行某些语句,不执行某些语句. JS中有三种语法是可以表示条件分支的 1.1 if……else…… 条件分支的主力语法,这个主力 ...

  2. 前端笔记之JavaScript(三)关于条件判断语句、循环语句那点事

    一.条件分支语句 条件分支语句,也叫作条件判断语句,就是根据某种条件执行某些语句,不执行某些语句. JS中有三种语法是可以表示条件分支的 1.1 if……else…… 条件分支的主力语法,这个主力语法 ...

  3. puppet(3) 变量、数据类型、表达式、条件判断语句-if、case、selector、unless

    puppet(4) 变量.数据类型.表达式.条件判断语句-if.case.selector语句 puppet变量: 1.名称必须以$开头:赋值使用=,支持追加赋值+=: 2.每个变量都有两种引用格式: ...

  4. python学习_条件判断语句_if

    #条件判断语句(if)#语法:if条件表达式:语句# 代码块#执行流程:if语句在执行时,会先对条件表达式进行求值判断#如果为True,则执行if后面的语句#如果为False,则不执行#默认情况下,i ...

  5. [19/09/16-星期一] Python的运算符和条件判断语句

    一.运算符 (1)算术运算符  + 加法运算符(如果是两个字符串之间进行加法运算,则会进行拼串操作) a = 10 + 5  计算 a = 'hello' + ' ' + 'world' 拼串  - ...

  6. Interview----求 1+2+...+n, 不能用乘除法、for、while if、else、switch、case 等关键字以及条件判断语句 (A?B:C)

    题目描述: 求 1+2+...+n, 要求不能使用乘除法.for.while.if.else.switch.case 等关键字以及条件判断语句 (A?B:C). 分析: 首先想到的是写递归函数,但是遇 ...

  7. 求1+2+…+n,要求不能使用乘除法、for、while、if、else、s witch、case 等关键字以及条件判断语句(A?B:C)和不用循环/goto/递归输出1~100的10种写法

    来源:据说是某一年某个公司的面试题 题目:求1+2+…+n, 要求不能使用乘除法.for.while.if.else.s witch.case 等关键字以及条件判断语句(A?B:C) 分析:这题本来很 ...

  8. if条件判断语句的不同

    let number = ["a":1, "b":2, "c":3]; if let num = number["d"] ...

  9. shell编程基础(3)条件判断语句

    1,带参数的shellscript #this is program build 5.11 to test shell script ############ cxz ####### 5.11 ### ...

随机推荐

  1. excel 数据导入数据表

    环境: Windows server 2012  rm sql server  2012 excel 数据导入数据表 INSERT INTO [dbo].[AdminUser] SELECT [Adm ...

  2. linux系统的目录讲解

    还记得在前面介绍c h m o d命令时讲过,目录的权限位和文件有所不同.现在我们来看看其中的区别.目录的读权限位意味着可以列出其中的内容.写权限位意味着可以在该目录中创建文件,如果不希望其他用户在你 ...

  3. 判断线段相交 -- 51nod 1264 线段相交

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1264 三角形的有向面积:a.x*b.y+b.x*c.y+c.x*a.y ...

  4. leetcode:Partition List

    题目:Given a linked list and a value x, partition it such that all nodes less than x come before nodes ...

  5. MDM平台学习笔记

    最近和将来一段时间都会花很多时间在主数据管理平台的学习和开发上,从现在开始打算记录此过程中的知识点和学习心得,加油! 1.IBM全新的产品文档网站IBM Knowledge Center,软件硬件产品 ...

  6. AI中去掉页面边框

    其实也没啥说的,就是很多人在百度中问这个在AI中这样除去页面边框,其实很简单,用快捷组合键  ctrl+shift+H  就行啦,边框自己就没了

  7. fix org.openqa.selenium.NoSuchWindowException when find element on windows8.1 ie11.

    Steps:1.I was able to resolve the issue after adding the site URL under trusted sites of IE. The sam ...

  8. 导出excel小结(C#,.NET,Wpf)

    range.NumberFormatLocal = "@";     //设置单元格格式为文本      range.NumberFormatLocal = "@&quo ...

  9. dotnet il editor 调试 iis 程序

    没有C#源代码,IL级别调试.听说windbg也可以,不过windbg有些难.另外il其实一般写C#程序也不熟,不过我目的只是找出异常点,到客户一般不发pdb文件,出去也是release版本,出异常( ...

  10. 中文web font技术及方案

    我们在日常需求中,经常会碰到视觉设计师对某个中文字体效果非常坚持的情况,因为页面是否高大上,字体选择是很重要的一个因素,选择合适的字体可以让页面更优雅.面对这种问题,我们通常以下方式来进行设计还原: ...