如何用IIFE命名空间创建JS库?(ES6前传统方案)
传统JS库的命名空间实现方案(ES6之前)
核心实现思路:立即执行函数表达式(IIFE)
用IIFE创建独立作用域,既能避免污染全局变量,又能把需要对外暴露的方法挂载到全局命名空间上,完全不需要ES6模块、第三方库或打包工具。
示例使用场景
假设用户的index.html调用方式如下:
<script src="canvas.js"></script> <script> // 通过全局命名空间调用库方法 CanvasLib.drawRectangle(10, 10, 100, 50); CanvasLib.setColor('#ff0000'); </script>
ES6实现对比(作为参考)
ES6通常用模块导出的方式实现:
// canvas.js (ES6模块) export function drawRectangle(x, y, w, h) { /* 具体实现 */ } export function setColor(color) { /* 具体实现 */ } // 使用时 import * as CanvasLib from './canvas.js'; CanvasLib.drawRectangle(10,10,100,50);
ES6之前的IIFE具体实现
基础版:直接挂载全局命名空间
// canvas.js (function(window) { // 私有变量/方法,外部无法访问 const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); function validatePos(x, y) { return x >= 0 && y >= 0; } // 要暴露的公共方法集合 const CanvasLib = { drawRectangle: function(x, y, width, height) { if (!validatePos(x, y)) return; ctx.fillRect(x, y, width, height); }, setColor: function(color) { ctx.fillStyle = color; }, clearCanvas: function() { ctx.clearRect(0, 0, canvas.width, canvas.height); } }; // 将命名空间挂载到全局window对象 window.CanvasLib = CanvasLib; })(window);
引入canvas.js后,就能直接通过CanvasLib调用所有暴露的方法。
安全版:避免覆盖已有同名命名空间
如果担心全局环境中已经存在CanvasLib变量,可以做兼容判断:
(function(window) { // 私有逻辑同基础版... // 若已有同名命名空间则复用,否则新建 window.CanvasLib = window.CanvasLib || {}; // 逐个添加公共方法 window.CanvasLib.drawRectangle = function(x, y, width, height) { /* 实现 */ }; window.CanvasLib.setColor = function(color) { /* 实现 */ }; })(window);
进阶版:支持模块扩展
如果需要拆分功能、分文件扩展库,可以让IIFE接收已有的命名空间:
// canvas-shapes.js 扩展模块 (function(window, CanvasLib) { // 新增圆形绘制方法 CanvasLib.drawCircle = function(x, y, radius) { ctx.beginPath(); ctx.arc(x, y, radius, 0, Math.PI * 2); ctx.fill(); }; })(window, window.CanvasLib);
只需先引入canvas.js,再引入canvas-shapes.js,就能使用新增的drawCircle方法。
方案优势
- 作用域隔离:私有变量和方法不会污染全局环境
- 命名空间清晰:用户通过统一前缀调用方法,避免变量冲突
- 零依赖:无需任何工具或第三方库,直接在浏览器中运行
内容的提问来源于stack exchange,提问作者Basj
相关产品推荐
相关产品推荐

