
本文解析 IIFE 内部具名函数表达式(如 (function b(){})())中,为何对函数名 b 的赋值操作无效——其本质是函数名在函数作用域内被绑定为不可写、不可配置的常量绑定,即使在非严格模式下赋值也静默失败。
本文解析 iife 内部具名函数表达式(如 `(function b(){})()`)中,为何对函数名 `b` 的赋值操作无效——其本质是函数名在函数作用域内被绑定为不可写、不可配置的常量绑定,即使在非严格模式下赋值也静默失败。
在 JavaScript 中,具名函数表达式(Named Function Expression, NFE) 的名称(如 b)具有特殊的绑定行为:它仅在函数体内部可见,且该绑定是不可修改的(immutable)。这与 var 或 let 声明的变量有根本区别。
以如下立即执行函数表达式为例:
(function b() {
console.log(b); // 输出:ƒ b() { ... }
b = 20;
console.log(b); // 依然输出:ƒ b() { ... },而非 20
})();表面看,b = 20 像是一次普通赋值,但实际它并未改变 b 的值。原因在于:
✅ 函数名 b 在该函数作用域中被创建为一个不可写(writable: false)、不可配置(configurable: false) 的绑定;
✅ 在非严格模式下,对该只读绑定的赋值操作会被静默忽略(no-op),不报错也不生效;
✅ 在严格模式下,则会立即抛出 TypeError: Assignment to constant variable. 类型错误,明确暴露问题。
验证严格模式下的行为:
(function b() {
'use strict';
console.log(b); // ƒ b() { ... }
b = 20; // ❌ TypeError: Assignment to constant variable.
console.log(b); // 此行不会执行
})();⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 此行为与函数声明(function b(){})不同:函数声明的名称也具不可写性,但作用域规则略有差异;而此处是函数表达式中的名称绑定,其生命周期严格限定于表达式自身函数体内;
- b 不是 var/let/const 声明的变量,因此不受变量提升或暂时性死区(TDZ)影响,而是由引擎在函数创建时自动建立的特殊词法绑定;
- 若需在函数内存储可变值,应显式使用独立变量(如 let value = 20;),而非试图覆盖函数名。
✅ 正确实践示例:
(function b() {
console.log('Function:', b); // ✅ 安全访问函数本身
let result = 20; // ✅ 使用新变量承载业务值
console.log('Value:', result); // 20
})();总结:函数表达式的名称(如 b)是只读的“活引用”(live reference)到函数对象本身,设计初衷是支持递归调用和调试识别,绝非用于重赋值的变量占位符。理解这一机制,有助于避免隐蔽的赋值失效陷阱,并写出更健壮、可维护的函数式代码。










