IE6–IE8中NFE函数名会泄露至外部作用域,导致typeof g返回"function"、f !== g、条件块内g被提前声明等异常行为。

具名函数表达式(Named Function Expression,NFE)在旧版 IE(特别是 IE6–IE8)中存在严重的作用域行为偏差,最典型的表现就是标识符意外泄露到外部作用域。识别该 Bug 的核心是观察函数名是否能在表达式外部被访问——这在标准 ECMAScript 中本应不可见,但在 JScript 引擎中却会“逃逸”出来。
检查函数名是否在外部可访问
这是最直接的识别方式。执行如下代码:
var f = function g() {};
typeof g; // 在 IE6–IE8 中返回 "function",标准浏览器中报 ReferenceError
若 g 未声明却能取到值,说明发生了作用域泄露。注意:该泄露可能污染全局作用域(如在全局上下文中执行),也可能污染外层函数作用域(如在函数内执行后,外层能访问 g)。
验证是否创建了两个独立函数对象
NFE 泄露常伴随“双重实例化”问题。可通过引用比较确认:
- var f = function g() {}; f === g; // IE6–IE8 返回 false(应为 true 或报错)
- f.expando = 'test'; g.expando; // g 上无该属性,证明 f 和 g 指向不同对象
这种分离意味着对 f 的扩展、绑定或缓存操作,对 g 完全无效,极易引发逻辑错误或状态不一致。
留意条件语句中的意外提升
JScript 会无视块级结构,将 NFE 当作函数声明提前解析。测试代码:
var f = function g() { return 1; };
if (false) { f = function g() { return 2; }; }
g(); // IE6–IE8 返回 2;标准环境抛 ReferenceError
即使分支永不执行,g 仍被重复声明并覆盖,说明 JScript 在解析阶段就扫描并注册了所有函数名,完全违背块级作用域语义。
结合调试工具快速定位
在 IE8 的 F12 开发者工具中,可在控制台直接输入函数名(如 g)查看是否可访问;也可在断点处展开作用域链,观察 Local / Global 下是否多出一个名为 g 的变量。若发现未定义却存在的函数标识符,基本可判定触发了该 Bug。











