zoukankan      html  css  js  c++  java
  • JavaScript形而上的单例模式

    什么是单例模式?

    单例模式是指,类多次实例化返回的对象是同一个。

    反例

    var tt = function(name){
        this.name = name;
    };
    
    var t1 = new tt('t1');
    var t2 = new tt('t2');
    
    console.log('t1和t2',t1 === t2);
    // => t1和t2 false
    

    上面的代码,t1和t2就不是同一个对象。
    同样的实例化方法,我们怎么让t1和t2是同一个对象?

    手动创建单例函数

    请看如下代码。

    var tt = function(name){
        this.name = name;
    };
    
    var ttSingleHandle = (function () {
        var instance;
        var singleFn = function(name){
            if (!instance) {
                instance = new tt(name);
            }
            return instance;
        }
        singleFn.prototype.construtor = tt;
        return singleFn;
    })();
    
    var t1 = new tt('t1');
    var t2 = new tt('t2');
    
    var t5 = new ttSingleHandle('t5');
    var t6 = new ttSingleHandle('t6');
    
    console.log('t1和t2',t1 === t2);
    console.log('t5和t6',t5 === t6);
    // => t1和t2 false
    // => t5和t6 true
    

    这里t5和t6是同一个对象。
    然而每次手动创建对应的单例函数效率不高,我们可以改造成单例工程函数。

    单例工厂函数

    var tt = function(name){
        this.name = name;
    };
    
    var singleFactory = function (fn) {
        var instance;
        var singleFn = function () {
            if(instance !== undefined){
                return instance;
            }
            else{
                var temp = fn.bind(this, ...arguments);
                instance = new temp();
                return instance;
            }        
        };
        singleFn.prototype.construtor = fn;
        return singleFn;
    };
    
    var t1 = new tt('t1');
    var t2 = new tt('t2');
    
    var ttSingle = singleFactory(tt);
    var t3 = new ttSingle('t3');
    var t4 = new ttSingle('t4');
    
    console.log('t1和t2',t1 === t2);
    console.log('t3和t4',t3 === t4);
    // => t1和t2 false
    // => t3和t4 true
    

    ES6的单例模式

    class Singleton {
        constructor(name) {
            this.name = name;
            this.instance = null;
        }
        static getInstance(name) {
            if(!this.instance) {
                this.instance = new Singleton(name);
            }
            return this.instance;
        }
    }
    
    var s1 = Singleton.getInstance('s1');
    var s2 = Singleton.getInstance('s2');
    console.log(s1 === s2);
    // => true
    

    因为截止2018年6月22日,ES6类不支持静态属性,只支持静态函数。
    静态属性的支持还在ES7提案中。
    假设支持静态属性,那么写法如下。

    class Singleton {
        static instance = null
    
        constructor(name) {
            if (!Singleton.instance) {
                this.name = name;
                instance = this;
            }
            return Singleton.instance;
        }
    }
    
    var s1 = new Singleton('s1');
    var s2 = new Singleton('s2');
    console.log(s1 === s2);
    // => true
    
  • 相关阅读:
    《Linux Device Drivers》第十二章 PCI司机——note
    Swift开放StatsD后上传数据的出现,出现退换货503的Bug
    google login page
    Use GraceNote SDK in iOS(一)通过序列化GDO查询专辑封面
    【人在职场】能力与价值
    HDU 5067-Harry And Dig Machine(DFS)
    LeetCode:Merge Two Sorted Lists
    HTML5硕士学习笔记
    通过设置注册表隐藏桌面图标
    SharePoint 要一个多行文本类型字段为特殊类型的链接
  • 原文地址:https://www.cnblogs.com/samwu/p/9258067.html
Copyright © 2011-2022 走看看