JS 的平凡之路 -- 单例模式的各种实现方式

栏目: JavaScript · 发布时间: 8年前

内容简介:JS 的平凡之路 -- 单例模式的各种实现方式

单例模式:保证一个类有且仅有一个实例,并且有一个全局访问点。虽然JavaScript中没有类的概念,但是我们依旧可以用很多方式模拟单例模式。

一、全局变量实现单例模式

用全局变量实现的单例模式:

var singleton = {
                num: 1,
                add: function (a) {
                    this.num += a;
                }
            }
            const s1 = singleton;
            const s2 = singleton;
            console.log(s1 === s2) // true

虽然这样可以实现一个单例模式,但是:

  • 全局变量很容易被污染(降低污染的方式可以使用命名空间和闭包封装私有变量);
  • 对于this的使用上可能会出现一些弊端,导致this不再指向例子中的singleton。

二、构造函数的静态属性实现单例

通过构造函数的静态属性来判断是否创建过实例:

function Singleton() {
                if (Singleton.instance) {
                    return Singleton.instance;
                }
                this.name = "单例";
                Singleton.instance = this;
            }

            const s1 = new Singleton();
            const s2 = new Singleton();
            console.log(s1 === s2); // true

这种方式看起来好像还不错,但是一旦你修改Singleton.instance就功亏一篑了。

三、利用代理实现单例模式

通过构造函数的静态属性的实现方法,我们可以发现单例的创建和判断的代码多放在了构造函数中,这其实违反了职责单一的原则。所以我们可以通过代理将这两部分的代码拆分开:

function Person(name) {
                this.name = name || '无名';
            }

            var ProxyCreatePersonSingleton = (function () {
                let _instance;
                return function () {
                    if (!_instance) {
                        _instance = new Person(arguments[0]);
                    }
                    return _instance;
                }
            })();

            const p1 = new ProxyCreatePersonSingleton('xiaoming');
            const p2 = new ProxyCreatePersonSingleton();
            console.log(p1 === p2); // true

但是有个缺点,比如我们突然要一个动物的单例,需要一个非常类似的代理方法,但是我们不得不重复的书写。

四、改造

function createSingle(fn) {
                 let _instance;
                 return function () {
                     return _instance || (_instance = fn.apply(this, arguments));
                 }
             }

             const personSingle = createSingle(_ => new Person);
             const p1 = personSingle();
             const p2 = personSingle();

             console.log(p1 === p2); // true

这里我们利用闭包和高阶函数的知识,减少重复的代码书写。

如果文章的内容能够帮助您,欢迎关注(^_^)。

GitHub

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Smashing Book

The Smashing Book

Jacob Gube、Dmitry Fadeev、Chris Spooner、Darius A Monsef IV、Alessandro Cattaneo、Steven Snell、David Leggett、Andrew Maier、Kayla Knight、Yves Peters、René Schmidt、Smashing Magazine editorial team、Vitaly Friedman、Sven Lennartz / 2009 / $ 29.90 / € 23.90

The Smashing Book is a printed book about best practices in modern Web design. The book shares technical tips and best practices on coding, usability and optimization and explores how to create succes......一起来看看 《The Smashing Book》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具