使用背景

https://github.com/LIlGG/halo-theme-sakura/pull/616/commits/af1e1572eabf654d53d498edd8b8d872e82a2198

IIFE 简介

在 Web 开发中,IIFE(Immediately Invoked Function Expression,立即调用函数表达式)是一种常见的 JavaScript 设计模式。它是一个在定义后立即执行的函数,通常用于创建新的作用域,避免全局命名空间的污染。

为什么在 Web 开发中使用 IIFE?

  • 避免全局变量冲突:在复杂的 Web 应用中,多个脚本或库可能定义同名变量。IIFE 能将变量限制在局部作用域内,防止冲突。
  • 数据隐私:IIFE 内部的变量和函数不会泄露到外部,适合封装模块或私有数据。
  • 执行初始化代码:IIFE 常用于执行一些只需要运行一次的代码,比如设置事件监听器或初始化配置。

IIFE 的用途

1. 避免全局变量污染

在 JavaScript 中,任何在全局作用域中声明的变量都会成为 window 对象的属性,容易导致变量名冲突。IIFE 创建了一个独立的作用域,确保变量不会影响全局环境。

2. 创建私有作用域

IIFE 允许开发者在函数内部定义私有变量和函数,这些内容无法从外部访问,类似于模块化开发中的私有成员。

3. 执行一次性初始化代码

IIFE 非常适合执行一些在页面加载时只需要运行一次的代码,比如初始化配置、绑定事件等。

IIFE 的基本语法

匿名函数的 IIFE

最常见的 IIFE 形式是使用匿名函数,并立即调用它:

(function() {
    var localVar = '我是局部的';
    console.log(localVar);  // 输出: 我是局部的
})();
  • (function() {...}):定义一个匿名函数。
  • ():立即调用该函数。
  • localVar 是一个局部变量,只能在 IIFE 内部访问。

带参数的 IIFE

IIFE 也可以接受参数,类似于普通函数:

(function(name) {
    console.log('Hello, ' + name);
})('World');  // 输出: Hello, World

IIFE 的示例

简单示例

下面的示例展示了如何使用 IIFE 来避免全局变量冲突:

// 脚本 1
(function() {
    var count = 0;
    console.log(count);  // 输出: 0
})();

// 脚本 2
(function() {
    var count = 1;
    console.log(count);  // 输出: 1
})();
  • 两个 IIFE 都定义了 count 变量,但它们互不干扰。

在模块化开发中的应用

IIFE 常用于创建模块,将内部变量和函数封装,仅暴露必要的接口:

var module = (function() {
    var privateVar = '私有变量';
    
    function privateFunction() {
        console.log('这是私有函数');
    }
    
    return {
        publicMethod: function() {
            console.log('这是公有方法');
        }
    };
})();

module.publicMethod();  // 输出: 这是公有方法
// module.privateFunction();  // 错误: privateFunction 未定义
  • privateVarprivateFunction 是私有的,外部无法访问。
  • publicMethod 是通过返回对象暴露的公有方法。

IIFE 的变体和替代方案

箭头函数的 IIFE

在 ES6 中,可以使用箭头函数来创建 IIFE:

(() => {
    console.log('箭头函数 IIFE');
})();
  • 箭头函数的 IIFE 更简洁,但不支持 thisarguments 的传统行为。

块级作用域(let 和 const)

在现代 JavaScript 中,letconst 提供了块级作用域,一定程度上减少了对 IIFE 的依赖:

{
    let localVar = '块级作用域变量';
    console.log(localVar);  // 输出: 块级作用域变量
}
// console.log(localVar);  // 错误: localVar 未定义
  • 块级作用域可以替代 IIFE 在某些场景下的使用,但 IIFE 仍然在模块化和一次性初始化方面有其优势。