
JavaScript 单例模式用静态属性保证 Popup 只创建一次在 JavaScript 中很多初学者会把单例模式理解成“只能new一次”。更准确的说法是把实例的创建和获取集中到一个入口让业务代码共享同一个对象。本文根据一个Popup示例解释static、getInstance()和a b的逻辑并指出当前示例存在的一个可运行性问题。源码静态阅读运行未验证。单例示例的目标代码希望让所有“打开网页”的操作共用一个Popup对象而不是每次点击按钮都newPopup();核心实现classPopup{staticins;staticgetInstance(){if(!Popup.ins){Popup.insnewPopup();}returnPopup.ins;}}static ins保存唯一实例static ins是类属性访问方式是Popup.ins而不是somePopup.ins它负责保存已经创建好的对象。第一次获取实例时它为空创建完成后它指向唯一的Popup对象。getInstance()控制创建时机staticgetInstance(){if(!Popup.ins){Popup.insnewPopup();}returnPopup.ins;}调用流程第一次 getInstance() → ins 不存在 → new Popup() → 保存到 Popup.ins → 返回实例 第二次 getInstance() → ins 已存在 → 不再 new → 返回原来的实例这就是延迟创建只有真正需要对象时才创建。为什么a b为 trueconstaPopup.getInstance();constbPopup.getInstance();console.log(ab);// true对象变量保存的是引用。a和b都拿到Popup.ins所以严格比较的结果为true。这不是两个内容相同的对象而是两个变量指向同一个对象。按钮事件如何使用单例constopenBtndocument.getElementById(openBtn);openBtn.addEventListener(click,(){a.open(https://www.baidu.com);});按钮点击时事件回调调用a.open()。设计意图是让Popup类统一管理打开网页这件事而不是把逻辑散落在不同的点击事件中。当前示例的关键问题Popup类中没有open()方法但按钮事件调用了a.open(https://www.baidu.com);因此点击按钮时可能报错TypeError: a.open is not a function被注释的代码window.open(https://www.baidu.com ,_blank);说明作者原本想让Popup.open()内部调用window.open()但这个方法还没有实现。_blank通常表示在新标签页或新窗口中打开页面。单例模式排查清单检查项正确状态是否有缓存实例的静态属性例如static ins是否有统一获取入口例如static getInstance()创建逻辑是否只在实例不存在时触发if (!Popup.ins)所有业务代码是否通过入口获取实例Popup.getInstance()调用的方法是否真的定义在类中当前open()未定义是否直接绕过入口执行new Popup()当前代码未限制需要团队约定面试怎么说可以这样回答单例模式通过一个静态属性保存实例并通过静态方法统一获取。第一次调用时创建实例后续调用直接复用因此适合管理配置、缓存、日志或模型等全局共享资源。JavaScript 中还要注意如果构造函数没有额外限制外部仍可以直接new所以单例通常依赖封装和使用约定。结语理解单例模式不要只记“只创建一个对象”。重点是理解谁负责创建、实例存在哪里、后续如何复用、业务代码是否绕过统一入口。下一步可以给Popup补上open()方法再在浏览器中验证按钮是否能打开新页面。本文未执行项目运行结果未验证。标签: JavaScript, 设计模式, 单例模式, DOM