IIFE通过函数表达式加立即调用创建独立私有作用域,隔离内部变量与函数以避免全局污染,支持传参依赖注入和返回对象暴露可控接口,虽被ES6模块取代,但在兼容旧环境、无构建工具场景仍有价值。

JavaScript中IIFE(Immediately Invoked Function Expression,立即执行函数表达式)的写法很简单:把一个函数表达式用括号包裹,再在后面加一对圆括号来调用它。它的核心作用就是创建一个独立的私有作用域,避免变量污染全局环境。
基础写法:两种常见形式
IIFE本质是“定义即执行”的函数表达式,关键在于让JS引擎把它识别为表达式而非函数声明(函数声明不能直接加括号执行)。
-
最常用写法:
(function() { /* 代码 */ })(); -
其他合法变体:
!function() { /* 代码 */ }();、~function() { /* 代码 */ }();、+function() { /* 代码 */ }();等——这些一元运算符强制将函数转为表达式,也能触发立即执行
为什么能构建私有作用域?
函数内部会形成自己的词法作用域。IIFE执行一次后,内部声明的变量、函数不会泄露到外层(包括全局),外部也无法直接访问它们,自然实现了封装和隔离。
- 内部用
var、let、const声明的变量只在该函数内有效 - 即使不写
var直接赋值(如name = 'Tom'),只要不是严格模式,仍会挂到全局;但规范写法应始终用声明关键字,确保私有性 - 闭包可让内部函数“记住”这个私有作用域,后续还能安全访问其中的数据
带参数和返回值的实用写法
IIFE常用来初始化模块、传入依赖(比如 window、document 或第三方库),也支持返回对象暴露有限接口。
立即学习“Java免费学习笔记(深入)”;
- 传参示例:
(function(global, doc) { console.log(doc.title); })(window, document); - 返回API示例:
const counter = (function() { let count = 0; return { inc() { count++; }, get() { return count; } }; })();—— 外部只能通过counter.inc()和counter.get()操作,count变量被完全隐藏
ES6之后还用IIFE吗?
模块化(import/export)和块级作用域(let/const)已成主流,IIFE不再是组织代码的首选。但它在以下场景仍有价值:
- 需要兼容老环境(如IE)且无法用模块打包时
- 一次性执行逻辑并隔离变量(比如循环中绑定事件,避免闭包陷阱)
- 模拟模块封装,尤其在UMD或IIFE格式的库输出中(如jQuery的源码头部)


















