函数表达式行为基本一致,差异源于运行环境:严格模式下具名表达式不可在内部引用自身名称;ES模块中不提升且无全局污染;CommonJS与ESM导出机制不同;旧版IE及嵌入式引擎存在兼容性问题。

函数表达式在不同运行环境(如浏览器、Node.js、ES模块、严格模式等)中行为基本一致,但几个关键细节会因环境配置或语言版本产生差异。
严格模式下无命名表达式的变量绑定限制
在严格模式中,具名函数表达式内部无法通过函数名访问自身(除非递归调用明确使用 arguments.callee,但该属性已被废弃):
- 非严格模式下:
const f = function named() { return named; };中named在函数体内可访问; - 严格模式下:
named在函数体内部不可引用,仅用于堆栈追踪和调试器显示; - 所有现代环境默认启用严格模式(模块脚本自动严格),因此该限制实际普遍生效。
模块环境(ESM)中顶层函数表达式不可被提升,且无全局污染
在 .mjs 文件或 <script type="module"> 中:
- 函数表达式定义的变量受
const/let规则约束,不会挂载到全局对象(如window或globalThis); - 即使写成
var fn = function() {};,也不会像传统 script 那样成为全局属性; - 模块作用域天然隔离,多个模块中同名函数表达式互不影响。
Node.js CommonJS 与 ESM 的导出差异
函数表达式作为模块出口时,行为取决于模块系统:
立即学习“Java免费学习笔记(深入)”;
- CommonJS 中:
module.exports = function() {};或exports.handler = function() {};直接赋值,支持动态覆盖; - ESM 中:
export default function() {};是语法声明,不可重复赋值;若用export const handler = function() {};,则遵循const语义,不可重绑定; - 注意:ESM 不允许在
export后接纯表达式(如export default (function(){})()),必须是声明或具名绑定。
旧版 IE 与极简运行时的兼容性边界
尽管已逐步淘汰,但在遗留系统维护中仍需留意:
- IE8 及更早版本不支持具名函数表达式在函数体内引用自身名称(即
function foo() { foo(); }在表达式中无效); - 某些嵌入式 JS 引擎(如早期 WebView 或 IoT 设备)可能不完全实现函数表达式的
name属性,导致fn.name返回空字符串; - 箭头函数(属于函数表达式语法糖)在 IE 完全不支持,需 Babel 转译或避免使用。
本质上,函数表达式本身语法稳定,差异主要来自宿主环境对作用域、模块系统和严格性的实现程度。只要避开老旧引擎、统一模块规范、启用严格模式,跨环境一致性就很有保障。


















