标准参考
函数声明和函数表达式
定义一个函数有两种途径:函数声明和函数表达式。
- 函数声明:
-
function Identifier ( FormalParameterList
opt) { FunctionBody }
- 函数表达式:
-
function Identifier
opt( FormalParameterList
opt) { FunctionBody }
ECMAScript 根据上下文来区分函数声明和函数表达式,假设 "function test(){}" 是一个表达式的一部分,它就是一个函数表达式,否则它就是一个函数声明。
关于函数声明和函数表达式的更多信息,请参考 ECMAScript 规范 13 Function Definition 中的内容。
标识符
在 ECMAScript 中,变量名、对象的属性或方法名都是标识符,标识符可以包含英文字母、数字、美元符号 '$' 和下划线 '_',但不能以数字开头,不能是保留字。
换句话说,'+','.' 等符号是不能出现在标识符中的。
关于标识符的更多信息,请参考 ECMAScript 规范 7.6 Identifier Names and Identifiers 的内容。
问题描述
IE 的函数声明和函数表达式的实现与 ECMA 规范都有出入。
在 IE 中:
函数声明中的标识符允许是一个包含 '.' 运算符的表达式。(在绑定事件时,可以将事件名前的 '.' 替换为 '::'。 )
函数表达式中的标识符则可以在该函数外部被访问。
造成的影响
依赖 IE 的上述“特性”编写的代码,在其他浏览器中将不能按照预期的方式执行。
例如以 'function window.onload() {}' 形式定义的事件处理函数仅在 IE 中有效,在其他浏览器中将报语法错误。
受影响的浏览器
IE6 IE7 IE8 |
---|
问题分析
1. 函数声明中的标识符允许是一个包含 '.' 运算符的表达式。(在绑定事件时,可以将事件名前的 '.' 替换为 '::'。 )
分析以下代码:
function A(){} function A.prototype.b(){} var a=new A(); alert(typeof a.b);
本例中,第二个函数声明的标识符是非法标识符,它包含了 '.' 运算符。
各浏览器表现如下:
IE6 IE7 IE8 | 其他浏览器 |
---|---|
function | 浏览器报错(语法错误) |
可见:以上写法只有 IE 支持。
2. 函数表达式中的标识符则可以在该函数外部被访问。
分析以下代码:
var a=function b(){}; alert(typeof b);
根据 ECMA 规范中的规定,以上函数表达式中的标识符 b 将仅在该函数的内部可以被访问,即 b 仅在该函数的作用域内有效,外部无法访问。
各浏览器表现如下:
IE6 IE7 IE8 | 其他浏览器 |
---|---|
function | undefined |
可见:IE 没有遵循规范,函数表达式中的标识符在该函数外围的作用域内也可以访问。
注:本文部分内容参考了文章:Named function expressions demystified(中文翻译:命名函数表达式探秘)中的内容。
解决方案
避免使用 IE 的这些“特性”,以保证兼容所有浏览器。
参见
知识库
相关问题
测试环境
操作系统版本: | 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-02 |
关键字
Named Function Declaration Expression 函数 声明 表达式
转载
http://w3help.org/zh-cn/causes/SJ9001