立即执行函数表达式-IIFE
作者: 更新: 4/9/2025 字数: 0 字 时长: 0 分钟
引言
在 ES6 出现以前,JavaScript 的世界里,我们经常会遇到一个棘手的问题:变量污染。由于 JavaScript 早期设计时没有模块系统,所有在全局作用域中声明的变量都会成为 window 对象的属性。这意味着:
var myVar = 'hello';
console.log(window.myVar); // 输出 'hello'
当项目变得庞大,多人协作开发时,这种设计会导致严重的命名冲突问题。想象一下,你定义了一个 count 变量,而同事也在另一个文件中定义了同名的 count 变量,后加载的文件会覆盖前者,导致难以追踪的 bug。
为了解决这个问题,业界先后实践出了下面几种方式:
命名空间模式
命名空间 的方式很简单,将那些可能污染全局的变量按功能模块收束到一个个对象属性中。
var MyApp = window.MyApp || {};
MyApp.utils = {
count: 0,
increment: function() {
this.count++;
}
};
这种方式确实减少了全局变量的数量,但仍然存在一些问题:
- 所有方法和属性必须通过命名空间对象访问
- 仍然有一个全局变量(如MyApp),没有根治问题
- 无法实现真正的私有变量(对象里面的属性还是可以被轻易访问)
IIFE的诞生
**立即执行函数表达式(IIFE, Immediately Invoked Function Expression)**应运而生,它完美解决了这些问题。IIFE的通常形式是:
(function() {
// 代码
})();
// 或者 推荐使用这种
(function() {
// 代码
}());
// 带参数例子
(function(a, b) {
console.log(a + b); // 输出 3
})(1, 2);
// 接受返回值
var result = (function() {
return 'Hello World';
})();
console.log(result); // 输出 "Hello World"
提示
上面的函数可以带函数名,也可以不带(匿名函数)。两者效果是一致的,因为即使有函数名也会被忽略,后续也无法被引用
重要
一定要注意 IIFE 全称是 立即执行函数表达式,而不是函数
- 为什么要在函数后面再加一对
()
?
因为只有表达式才能被执行。单纯的函数声明、定义没法执行。
- 它的原理是什么呢?
很简单,不要被它的结构迷惑了。就是把一个函数从声明转成表达式。比如 function test(){}
这是 声明函数, 它后面就不能加 ()
运行。为什么?因为它是函数,而不是表达式。
那现在我把它转成表达式,如何转?很简单,基本上任何形式都可以:
比如:var a = function test(){}()
这是一个赋值表达式,这个就可以运行😂! 还有 +function test(){}()
或者前面加 -&&!
等任意符号,都可以运行(别惊讶,真的可以),因为都转成了表达式。
既然加这些符号都可以,那为什么我们见到的都是用 ()
?
因为 ()
的本质作用就是执行的意思。而其他符号也有自己的本质作用,比如 +
是转成数字类型,!
有取反的意思。所以最后大家基本都约定用 ()
。
最后表达式执行完了,这个函数也就销毁了(这就是为什么即使带了函数名也没用)。所以通常 IIFE 会用在初始化或者只运行一次的地方。