单例模式,也就是要确保在某一个类在全剧中只有一个实例,并且提供一个全局的访问点来访问这一实例。
如何实现一个单例模式,主要讲究两个字,一个字“存”,在类内存在一个属性,如果这个属性不为空那么就初始化当前类赋值给这一属性,另一个字“堵”,将所有的可能再次实例化当前类的方法都“堵”住,并且返回“存”的实例,当然在第一个次实例的时候需要正常实例化,也就是存放实例的属性为空时,可以正常实例化。
在前端开发中可以使用闭包实现单例模式(当然也可以使用 Class 语法糖或者构造函数形式实现),我们将设想一个案例:将一些配置内容或者一些其他内容放在一个单例中供其他内容访问。
首先我们将通过闭包实现一个配置信息的管理,首先我们写一个简单的闭包代码,使 config
属性不受外部污染。
1 2 3 4 5 6
| const createConfig = (() { let config; return () => { return config; } })()
|
但是我们要实现一个单例模式,就要在再次返回config
前做判断,如果没有 config
要对他进行“实例化“并返回,如果存在 config
就将cunfig返回。
1 2 3 4 5 6 7 8 9 10 11
| const createConfig = (() => { let config; return () => { if (!config) { config = { }; } return config; } })()
const config = createConfig();
|
当然这就完成了一个简单的配置对象的单例,但是我们发现现在的 createConfig
和直接返回一个对象没有什么区别,这是为什么?
有了配置对象的单例,不对对象进行操作基本上没什么用,属于”为醋包饺“,不提倡。
接下来我们将要实现的是,为配置对象新增 set
方法,这个方法将传入两个参数,分别是 key
和 value
,作用就是将对象中的 key
的值改成 value
传入的内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| const createConfig = (() => { let instance; return () => { if (!instance) { instance = { config: {}, set ( key, value ) { this.config[key] = value; } }; } return instance; } })();
const config1 = createConfig(); const config2 = createConfig(); console.log( 'config1:', config1.config, 'config2:', config2.config );
config1.set('key', 0); console.log('config2.config', config2.config);
|
当然在前端中不可能是一个页面打开一直不关闭,所以我们就要对数据进行缓存,一下案例中使用了 localStorage
和 JSON
对数据进行了处理,只能处理简单数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| const createConfig = (() => { let instance; return () => { if (!instance) { const config = JSON.parse(localStorage.getItem('config') ?? '{}') instance = { config, set ( key, value ) { this.config[key] = value; localStorage.setItem('config', JSON.stringify(this.config ?? {}) ); } }; } return instance; } })();
const config1 = createConfig(); const config2 = createConfig(); console.log( 'config1:', config1.config, 'config2:', config2.config );
config1.set('key', 0); console.log('config2.config', config2.config);
|
todo 使用 ES6 class形式 完成单例模式
todo 使用 构造函数形式 完成单例模式