早期javascript用iife+对象字面量模拟模块化:通过闭包封装私有变量与函数,仅暴露公共api;支持模块拼接与依赖注入,需注意括号语法、严格模式及显式return。

在早期 JavaScript(ES5 及更早)中,没有 module、import 或 export,命名空间需手动隔离作用域。对象字面量配合自执行函数(IIFE)是最经典、最可靠的模拟方式——它既避免全局污染,又支持私有变量与公共接口分离。
用对象字面量定义命名空间结构
对象字面量本身不提供封装,但它是组织公开 API 的天然容器。例如:
var MyApp = { utils: {}, core: {}, version: "1.0"
};
这仅是“壳”,所有属性默认可被外部修改或覆盖。真正关键在于:把该对象作为 IIFE 的返回值,让内部逻辑受闭包保护。
用 IIFE 封装私有实现并返回命名空间对象
IIFE 执行时创建独立作用域,内部声明的变量、函数对外不可见;只通过显式返回的对象暴露接口:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
var MyApp = (function () { // 私有变量
var _config = { debug: true }; // 私有工具函数
function _log(msg) { if (_config.debug) console.log("[MyApp]", msg); }
// 公共命名空间对象
return { version: "1.0",
utils: { format: function (str) { return str.toUpperCase(); }, isValid: function (x) { return x != null; } },
core: { init: function () { _log("initialized"); } }
};
})();
此时 _config 和 _log 完全无法从外部访问,而 MyApp.utils.format 等路径清晰、层级明确,形成“高级命名空间”的语义效果。
支持模块化拼接与依赖注入
多个功能模块可各自封装为 IIFE,并通过参数接收已有命名空间对象,实现安全扩展:
// 模块 A
var MyApp = (function (ns) { ns.auth = { login: function() { /* ... */ } }; return ns;
})(MyApp || {});// 模块 B(依赖 A)
var MyApp = (function (ns) { ns.auth.logout = function() { /* ... */ }; return ns;
})(MyApp || {});
- 使用
MyApp || {}防止未定义报错,兼容脚本加载顺序 - 每个模块只负责自己部分,不破坏已有属性
- 外部调用统一走
MyApp.auth.login(),使用者无需关心模块拆分细节
注意点与常见陷阱
-
不要省略括号:写成
function(){...}()是语法错误;必须包裹在括号内,如(function(){...})()或(function(){...}()) -
避免意外全局变量:IIFE 内部忘记用
var声明变量,会泄漏到全局(如counter = 0),务必严格启用"use strict" -
命名空间对象必须 return:若 IIFE 内部只做初始化却不返回对象,
MyApp将是undefined -
慎用
this:在非严格模式下,IIFE 中的this指向window,易引发误用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










