JavaScript中两种匿名函数写法的差异及间接封装的作用是什么?
Case B写法解读
Case B使用了**IIFE(立即执行函数表达式)**语法,执行逻辑分为两步:
- 定义匿名外层函数后立刻通过尾部的
()执行该函数 - 外层函数执行完成后,将内部返回的
half函数赋值给常量half
你可以将最终的half解读为:接收stats作为输入并返回对应值的函数,当前示例下和Case A的调用表现完全一致。如果你熟悉C++,这种写法类似你在一个独立块作用域内定义变量,再返回捕获了这些变量的lambda,块作用域销毁后外部无法访问内部的私有变量,只有返回的lambda可以访问。
Case B的额外特性
当前示例中外层IIFE没有额外逻辑,所以两种写法没有区别。IIFE的核心能力是创建独立的私有作用域,外层IIFE内定义的变量、方法仅内部可见,外部作用域无法直接访问,仅返回的函数可以通过闭包访问,常见用法有:
- 封装私有状态:比如需要统计函数调用次数,不需要把计数变量暴露到全局:
const half = (function() { // 私有变量,外部无法直接读写 let callCount = 0; return function half(stats) { callCount++; return (stats.max + stats.min) / 2.0; }; })();
- 执行一次性初始化逻辑:如果返回函数依赖的常量只需要计算一次,可以放在IIFE里执行,避免每次调用函数重复计算:
const half = (function() { // 初始化逻辑仅执行一次 const adjustFactor = 0.98 * Math.PI; return function half(stats) { return (stats.max + stats.min) / 2.0 * adjustFactor; }; })();
- 避免全局作用域污染:ES6模块规范普及前,前端普遍使用IIFE封装业务逻辑,防止全局变量命名冲突。
适用场景
没有绝对必须使用IIFE的场景,它的所有能力都可以通过ES6的块级作用域、模块、类私有属性等新特性替代。但在以下场景下使用IIFE会更简洁:
- 需要兼容ES5及以下的旧运行环境
- 需要快速封装一个带私有状态的工具函数,不需要额外定义模块或者类
内容的提问来源于stack exchange,提问作者aerialmyth
相关产品推荐
相关产品推荐

