zoukankan      html  css  js  c++  java
  • JavaScript之单例实战

    一、概述

    所谓单例模式,顾名思义即一个类只有一个实例。

    所以,当我们创建一个实例时,就必须判断其是否已经存在了这个实例,如果已经存在了这个实例,那么就返回这个已经存在的实例,无需再创建一个单例模式嘛,核心就是一个类只有一个 实例;如果不存在,就创建这个实例咯。

    好了,单例模式的核心思想以及创建流程大致搞清楚了,那么我们就开始看看,在Javascript的世界中,具体该怎么实现呢?

    二、实战一

    核心思路:利用Javascript的作用域,形成闭包,从而可以创建私有变量(假设我们将这个私有变量取名为instance),然后将创建的实例赋予这个私有变量instance就ok了。每当想创建这个类的实例时,先判断instance是否已经引用了存在的实例,如果没有引用,即这个类没有被创建实例,so创建一个实例,然后将其赋予给instance;如果instance已经引用,即已存在了该类的实例,so无需再创建,直接使用这个instance就ok了。

    第一步:执行匿名函数,防止命名空间污染。在匿名函数中,首先定义个上述提到的私有变量instance以及一个类。这个类,我假设它有名字(name)和年龄(age)两个属性字段以及一个输出他们名字的方(displayInfo)哈。

    'use strict'
    var singletonAccepter =(function(){
        //默认将instance赋予null
        var instance = null;
        //类:SupposeClass
        function SupposeClass( args ){
            var args = args || {};
            this.name = args.name || 'Monkey';
            this.age = args.age || 24;
        };
        SupposeClass.prototype = {
            constructor: SupposeClass,
            displayInfo: function(){
                console.log('name: ' + this.name + '   age: ' + this.age);
            }
        };
    })();

    第二步:利用return + 对象字面量,将我们想,向外暴露的东东,往外抛。

    如下:

    return {
        //类的名字
        name: 'SupposeClass',
        //创建类的实例方法
        getInstance: function( args ){
            //利用私有变量instance实现单例模式
            if( instance === null ){
                instance = new SupposeClass( args );
            }
            return instance;
        }
    };

    最后,合并第一步第二步的代码就形成了一个单例模式啦。

    如下:

    'use strict'
    var singletonAccepter =(function(){
        //默认将instance赋予null
        var instance = null;
        //类:SupposeClass
        function SupposeClass( args ){
            var args = args || {};
            this.name = args.name || 'Monkey';
            this.age = args.age || 24;
        };
        SupposeClass.prototype = {
            constructor: SupposeClass,
            displayInfo: function(){
                console.log('name: ' + this.name + '   age: ' + this.age);
            }
        };
        return {
            //类的名字
            name: 'SupposeClass',
            //创建类的实例方法
            getInstance: function( args ){
                //利用私有变量instance实现单例模式
                if( instance === null ){
                    instance = new SupposeClass( args );
                }
                return instance;
            }
        };
    })();

    接下来,我们检验一下写的这个单例模式。在上述代码中,在类SupposeClass中加入console.log,如果只创建了它的一个实例,那么就只会打印一个日志哦。
    修改代码如下:

    'use strict'
    var singletonAccepter =(function(){
        var instance = null;
        function SupposeClass( args ){
            var args = args || {};
            this.name = args.name || 'Monkey';
            this.age = args.age || 24;
            //检验单例模式
            console.log('this is created!');
        };
        SupposeClass.prototype = {
            constructor: SupposeClass,
            displayInfo: function(){
                console.log('name: ' + this.name + '   age: ' + this.age);
            }
        };
        return {
            name: 'SupposeClass',
            getInstance: function( args ){
                if( instance === null ){
                    instance = new SupposeClass( args );
                }
                return instance;
            }
        };
    })();

    调用两次getInstance方法,看看打印几条记录

    singletonAccepter.getInstance();
    singletonAccepter.getInstance();

    执行代码,打开chrome截图如下:

    鉴定完毕,只被实例一次。

    三、实战二

    思路:利用属性来判断是否已存在实例。
    什么意思?
    在Javascript的世界里,类(function)不也是对象嘛,so对其赋予一个属性instance,用来引用创建的实例,通过判断instance是否已引用创建的实例就OK咯。

    如下:

    function singletonAccepter( args ){
        //判断Universe.instance是否已存在实例
        if(typeof singletonAccepter.instance === 'object'){
            return singletonAccepter.instance;
        }
        this.name = args.name || 'Monkey';
        this.age = args.age || 24;
        singletonAccepter.instance = this;
    };
    singletonAccepter.prototype = {
        constructor: singletonAccepter,
        displayInfo: function(){
            console.log('name: ' + this.name + '   age: ' + this.age);
        }
    };
    四、实战三

    在Javascript的世界里,this是引用的对象。
    还记得JavaScript是怎么通过new创建对象的么?
    new:
      1、创建一个新的对象,这个对象的类型时object;
      2、将这个对象的__proto__隐指针指向原型prototype;
      3、执行构造函数,当this被提及的时候,代表新创建的对象;
      4、返回新创建的对象。
      注:倘若在最后return了,那么return的是基本类型,例如3,则无效;否则是引用类型,则返回这个引用类型。


    注意第3点了么?

    当new后,this代表新创建的对象。so,我们可以利用闭包,在类中声明一个变量instance来引用创建的实例。然后再重写类,就OK啦。

    如下:

    function singletonAccepter( args ){
        var instance = null;
        var args = args || {};
        this.name = args.name || 'Monkey';
        this.age = args.age || 24;
        //将instance引用创建的实例this
        instance = this;
        //重写构造函数
        singletonAccepter = function(){
            return instance;
        }
    };
    singletonAccepter.prototype = {
        constructor: singletonAccepter,
        displayInfo: function(){
            console.log('name: ' + this.name + '   age: ' + this.age);
        }
    };
  • 相关阅读:
    IDEA添加注释模板
    Docker安装Mysql
    Linux使用
    Linux使用
    Spring Cloud入门 (5)
    在IDEA中将SpringBoot项目打包成jar包
    Linux使用
    Linux使用
    Linux使用- 虚拟机安装 Linux
    Spring Cloud入门 (4)
  • 原文地址:https://www.cnblogs.com/giggle/p/5452271.html
Copyright © 2011-2022 走看看