函数
IIFE 与模块模式
掌握立即执行函数、模块暴露模式
IIFE 与模块模式
IIFE(立即执行函数)是 ES6 模块出现前的模块化方案。
学完本章你将: 理解 IIFE 原理、模块暴露模式。
什么是 IIFE
javascript
// IIFE = Immediately Invoked Function Expression
(function() {
console.log("我立即执行!");
})();
// 多种写法
(function() { console.log("A"); })(); // 经典
(function() { console.log("B"); }()); // 也有效
!function() { console.log("C"); }(); // 用 ! 开头
+(function() { console.log("D"); })(); // 用 + 开头
为什么需要 IIFE
javascript
// 问题:全局变量污染
var name = "Alice";
// ... 其他代码 ...
var name = "Bob"; // 覆盖了!
console.log(name); // "Bob"
// 解决:用 IIFE 创建独立作用域
(function() {
var name = "Alice"; // 局部变量
console.log(name); // "Alice"
})();
// 外面的代码不受影响
var name = "Bob";
console.log(name); // "Bob"
IIFE 传参
javascript
// 向 IIFE 传参
(function(greeting, name) {
console.log(`${greeting}, ${name}!`);
})("你好", "Alice"); // "你好, Alice!"
// 传入全局对象
(function(global) {
console.log(global === window); // true(浏览器)
})(this);
模块暴露模式(Revealing Module Pattern)
javascript
// 用 IIFE 实现模块
const UserModule = (function() {
// 私有变量和函数
let users = [];
function privateValidate(user) {
return user && user.name;
}
// 公开 API
return {
add(user) {
if (privateValidate(user)) {
users.push(user);
return true;
}
return false;
},
getAll() {
return [...users]; // 返回副本
},
count() {
return users.length;
},
};
})();
UserModule.add({ name: "Alice" });
UserModule.add({ name: "Bob" });
console.log(UserModule.getAll()); // [{ name: "Alice" }, { name: "Bob" }]
console.log(UserModule.count()); // 2
// UserModule.users; // undefined(私有)
IIFE vs ES6 模块
| 特性 | IIFE | ES6 模块 |
|---|---|---|
| 作用域隔离 | ✅ | ✅ |
| 依赖管理 | 手动 | import/export |
| 异步加载 | ❌ | ✅ |
| 静态分析 | ❌ | ✅ tree-shaking |
javascript
// 现代 JS 中直接用 ES6 模块
// user.module.js
let users = [];
export function addUser(user) { users.push(user); }
export function getUsers() { return users; }
// main.js
import { addUser, getUsers } from './user.module.js';