立即执行函数表达式(IIFE,Immediately Invoked Function
Expression)曾是我们的救星,它帮助我们避免全局污染,创建私有作用域,解决了许多令人头疼的问题。但是,随着块级作用域的引入,让我们有了更优雅的解决方案。
IIFE:曾经的英雄,如今的累赘
IIFE 的经典用法
在 ES6 之前,我们经常这样写代码:
// 经典的 IIFE 模式
(function() {
var privateVar = '这是私有变量';
var counter = 0;
function increment() {
counter++;
console.log('当前计数:', counter);
}
// 只暴露需要的接口
window.myModule = {
increment: increment
};
})();
或者用于避免循环中的闭包陷阱:
// 使用 IIFE 解决循环闭包问题
for (var i = 0; i < 5; i++) {
(function(index) {
setTimeout(function() {
console.log('索引:', index);
}, 100);
})(i);
}
IIFE 的问题
虽然 IIFE 解决了作用域问题,但它也带来了一些困扰:
- ** 语法臃肿 ** :需要额外的括号和函数声明
- ** 可读性差 ** :嵌套层级增加,代码变得难以理解
- ** 调试困难 ** :匿名函数在调试时不好定位
- ** 不够语义化 ** :代码意图不够明确
块级作用域:现代 JavaScript 的优雅方案
使用 let/const 替代 var
ES6 引入的 let 和 const 具有块级作用域特性,让我们可以抛弃复杂的 IIFE:

循环中的块级作用域
最明显的改进体现在循环中:

条件块中的作用域隔离

性能对比:为什么块级作用域更好
内存使用

执行效率
块级作用域不需要创建函数调用栈,执行效率更高:
// 测试执行时间
console.time('IIFE');
for (let i = 0; i < 100000; i++) {
(function() {
const temp = i * 2;
const result = temp + 1;
})();
}
console.timeEnd('IIFE');
// => IIFE: 8.159912109375 ms
console.time('Block Scope');
for (let i = 0; i < 100000; i++) {
{
const temp = i * 2;
const result = temp + 1;
}
}
console.timeEnd('Block Scope');
// => Block Scope: 1.242919921875 ms
IIFE 曾经是 JavaScript 开发中不可或缺的工具,但随着语言的发展,块级作用域为我们提供了更优雅、更现代的解决方案。通过使用 let
、 const 和块级作用域,我们可以:
- ** 写出更清晰的代码 ** :语法更简洁,意图更明确
- ** 获得更好的性能 ** :避免不必要的函数调用开销
- ** 享受更好的调试体验 ** :更容易定位问题和理解代码流程
- ** 符合现代开发趋势 ** :与 ES6+ 特性更好地集成