当前位置: 首页 > 科技观察

面试官:谈谈你对单例模式的理解?如何实现?

时间:2023-03-22 11:54:39 科技观察

本文转载自微信公众号《JS日报》,作者灰灰。转载本文请联系JS每日一问公众号.1、什么是单例模式(SingletonPattern):一种创建型模式,提供了创建对象的最佳方式。这种模式涉及单个类负责创建自己的对象,同时保证在应用程序运行过程中只有一个对象被创建,单例模式只会在全局范围内创建一次实例对象,这样所有地方需要调用的共享这个单例对象,如下图:从定义上看,全局变量似乎是单例模式,但一般我们不会认为全局变量是单例模式,原因是:全局命名污染不易维护,容易被改写覆盖。表示当前类已经创建了一个对象。如果下次获取当前类的实例,可以直接返回之前创建的对象,如下://DefineaclassfunctionSingleton(name){this.name=name;this.instance=null;}//原型扩展类的一个方法getName()Singleton.prototype.getName=function(){console.log(this.name)};//获取类Singleton.getInstance=function(name){if(!this.instance){this.instance=newSingleton(name);}returnthis.instance};//获取对象1consta=Singleton.getInstance('a');//获取对象2constb=Singleton.getInstance('b');//比较console.log(a===b);也可以使用闭包,如下:functionSingleton(name){this.name=name;}//原型扩展类的一个方法getName()Singleton.prototype.getName=function(){console.log(this.name)};//获取类的实例Singleton.getInstance=(function(){varinstance=null;returnfunction(name){if(!this.instance){this.instance=newSingleton(name);}returnthis.插件tance}})();//获取对象1consta=Singleton.getInstance('a');//获取对象2constb=Singleton.getInstance('b');//比较console.log(a===b);也可以对上面的方法稍作修改,形成一个构造函数,如下://Singleton构造函数functionCreateSingleton(name){this.name=name;this.getName();};//获取一个实例CreateSingleton.prototype的名字.getName=function(){console.log(this.name)};//单例对象constSingleton=(function(){varinstance;returnfunction(name){if(!instance){instance=newCreateSingleton(name);}returninstance;}})();//创建实例对象1consta=newSingleton('a');//创建实例对象2constb=newSingleton('b');console.log(a===b);//true3.在前端,很多时候都是用单例模式。比如页面上有模态框的时候,只有在用户点击的时候才会创建,而不是加载完成后才创建弹窗。window和hide,并且保证弹窗只有一个方法先创建一个普通对象,如下:constgetSingle=function(fn){letresult;returnfunction(){returnresult||(result=fn.apply(这个,参数));}};创建弹窗的代码如下:constcreateLoginLayer=function(){vardiv=document.createElement('div');div.innerHTML='我是浮窗';div.style.display='none';document.body.appendChild(div);returndiv;};constcreateSingleLoginLayer=getSingle(createLoginLayer);文档ument.getElementById('loginBtn').onclick=function(){varloginLayer=createSingleLoginLayer();loginLayer.style.display='block';};上面的实现称为惰性单例,只有在解决需要Instance对象时才会创建类,而Vuex和redux全局状态管理库也应用了单例模式的思想,如图下图:现在很多第三方库都是单例模式,多次引用只会使用同一个对象,比如jquery,lodash,moment...参考资料https://zh.wikipedia.org/zh-hans/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8Fhttps://www.runoob.com/design-pattern/singleton-pattern.htmlhttps://juejin.cn/post/6844903874210299912#heading-5