标准参考

函数声明和函数表达式

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

函数声明:
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. Maven+Spring+Hibernate+Shiro+Mysql简单的demo框架(一)

    相关的maven的 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="ht ...

  2. HUD-1142

    A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

  3. 单调递增最长子序列(南阳理工ACM)

    描述 求一个字符串的最长递增子序列的长度如:dabdbf最长递增子序列就是abdf,长度为4 输入 第一行一个整数0<n<20,表示有n个字符串要处理随后的n行,每行有一个字符串,该字符串 ...

  4. Kobject结构体分析

    kobject是组成设备device.驱动driver.总线bus.class的基本结构.如果把前者看成基类,则后者均为它的派生产物.device.driver.bus.class构成了设备模型,而k ...

  5. MongoDB 学习笔记(一)基础篇

    1.MongoDB 特点 面向集合存储,存储对象类型的数据方便 模式自由,不需要定义任何模式(schma) 动态查询 完全索引,包含内部对象 复制和故障恢复方便 高效的二进制数据存储 支持c# 平台驱 ...

  6. leetcode:Number of 1 Bits

    Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also know ...

  7. binary-tree-maximum-path-sum(mock)

    注意: // 注意,如果一个类放在另一个类里面,初始化时候会报错 Solution is not a enclosing class// 这是因为如果TreeNode不是static,那么要求先有外部 ...

  8. Android 第三方应用接入微信平台(2)

    微信平台开放后倒是挺火的,许多第三方应用都想试下,毕竟可以利用微信 建立起来的关系链来拓展自己的应用还是挺不错的,可以节约很多在社交方 面的开销,我最近由于实习需要也在研究这个东西,不过发现网上的相关 ...

  9. bzoj1564: [NOI2009]二叉查找树

    dp. 首先这棵树是一个treap. 权值我们可以改成任意实数,所以权值只表示相互之间的大小关系,可以离散化. 树的中序遍历是肯定确定的. 用f[l][r][w]表示中序遍历为l到r,根的权值必须大于 ...

  10. HDU 1058 Humble Numbers【DP】

    题意:给出丑数的定义,只含有2,3,5,7这四个素数因子的数称为素数.求第n个丑数. 可以先观察几个丑数得出规律 1:dp[1] 2:min(1*2,1*3,1*5,1*7) 3:min(2*2,1* ...