抛弃立即执行函数 (IIFE),让 JavaScript 代码更丝滑


立即执行函数表达式(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 解决了作用域问题,但它也带来了一些困扰:

  1. ** 语法臃肿 ** :需要额外的括号和函数声明
  2. ** 可读性差 ** :嵌套层级增加,代码变得难以理解
  3. ** 调试困难 ** :匿名函数在调试时不好定位
  4. ** 不够语义化 ** :代码意图不够明确

块级作用域:现代 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+ 特性更好地集成