IIFE是立即执行的函数表达式,非函数声明;通过括号、!、+、void等强制表达式化,用于解决变量污染和作用域隔离问题,在现代JS中虽被模块和块级作用域替代,但在非模块环境、UMD封装及临时作用域场景仍有价值。
IIFE(Immediately Invoked Function Expression)本质是「定义完立刻执行」的函数表达式,不是函数声明。关键区别在于:JS 引擎看到 function 开头时,若后面紧跟 (...),会按表达式解析;若以 function name() {...} 独立出现,则是声明,不能直接加括号调用,否则报错 Uncaught SyntaxError: Unexpected token '('。
常见写法都围绕「强制表达式化」展开,比如加括号、取反、void 运算等:
(function() { ... })(); —— 最常用,外层括号让 JS 认为这是分组表达式!function() { ... }(); 或 +function() { ... }(); —— 一元运算符也强制表达式上下文void function() { ... }(); —— void 总是返回 undefined,适合不关心返回值的场景在 ES6 let/const 和模块系统普及前,IIFE 是前端隔离作用域的主要手段。全局作用域里反复声明 var i、var utils 容易冲突,而 IIFE 内部的 var 不会泄漏到外部。
典型使用场景包括:
(function($) { ... })(jQuery); 中,确保 $ 指向预期对象for (var i = 0; i console.log(i), 0) 全输出 3,改用 for (var i = 0; i console.log(i), 0); })(i);
var count = 0 外部无法访问,仅通过返回的函数暴露接口IIFE 支持传参,但必须严格匹配形参个数和实参顺序。容易出错的是「误把全局变量当参数传入」或「忘记传参导致 undefined」。
例如这段代码:
(function(window, document, undefined) {
console.log(window === window); // true
console.log(document); // 正常
console.log(undefined === void 0); // true,防止 undefined 被重写
})(window, document);
注意三点:
undefined,但没传实参 → 自动为 undefined,且无法被外部篡改(旧版 IE 允许赋值给 undefined)document,第二个形参就变成 undefined,后续调用 document.getElementById 会报错function(window, document) {}(window, document) —— 缺少外层括号,JS 会尝试解析为函数声明,语法错误ES6 模块(import/export)、let/const 块级作用域、以及打包工具(Webpack/Vite)已覆盖大部分 IIFE 的原始用途。但仍有不可替代的场景:
const uid = (function() { let i = 0; return ()
=> ++i; })();
真正容易被忽略的是:IIFE 内部的 this 指向 —— 非严格模式下是 window(或 globalThis),严格模式下是 undefined。如果函数里用了 this.xxx 又没绑定,行为可能和预期不符。