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);
    }
};
时间: 2024-08-23 11:56:40

JavaScript之单例实战的相关文章

Javascript 设计模式 单例

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/30490955 一直很喜欢Js,,,今天写一个Js的单例模式实现以及用法. 1.单例模式的写法 单例模式写法相当简单: var singleTon = { m1: "memeber first ", m2: "memeber second ", f1: function () { console.log("fun1 "); } }

Javascript 设计模式 单例 http://blog.csdn.net/lmj623565791/article/details/30490955/

转载请标明出处:http://blog.csdn.NET/lmj623565791/article/details/30490955 一直很喜欢Js,,,今天写一个Js的单例模式实现以及用法. 1.单例模式的写法 单例模式写法相当简单: [javascript] view plain copy var singleTon = { m1: "memeber first ", m2: "memeber second ", f1: function () { consol

[Js高手之路第一部]JavaScript上百例实战【新版】_1 js代码三种书写方式

小结: javascript使用的3种方式: 1,页面script方式 2,行间事件触发 3,外部引入方式 1,页面script方式 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <script> 7 alert(1); 8 <

[Js高手之路第一部]JavaScript上百例实战【新版】_3 javascript变量的类型

JavaScript 数据类型 字符串.数字.布尔.数组.对象.Null.Undefined 1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title></title> 6 <script> 7 //变量的类型由 变量的值来决定 8 // 弱类型语言 9 10 //字符串类型, 用引

[Js高手之路第一部]JavaScript上百例实战【新版】_2 javascript变量命名&amp;使用规则

变量 1,什么是变量 变量是内存中用来存储数据的一块区域 2,变量的命名规则 3,怎么使用变量 var 变量名 =(赋值) 10 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <script> 7 var name='name'; 8

[Js高手之路第一部]JavaScript上百例实战【新版】_8 javascript二重循环,break与continue语句

输出5行5列的表格 使用二重循环实现 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style> 7 table { 8 /*合并单元格之间的线*/ 9 border-collapse: collapse; 10 } 11 th,t

[Js高手之路第一部]JavaScript上百例实战【新版】_9 javascript二重循环乘法表与n行n列的表格

0.隔行变色的表格 HTML style 属性实现 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style> 7 table { 8 /*合并单元格之间的线*/ 9 border-collapse: collapse; 10 }

[Js高手之路第一部]JavaScript上百例实战【新版】_10 javascript输出一个对角线形状的div

1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style> 7 div { 8 width: 50px; 9 height: 50px; 10 background: palevioletred; 11 position: abso

[Js高手之路第一部]JavaScript上百例实战【新版】_20 读取样式与className和屏蔽空的锚

<input type="button" value="恢复样式" onclick="resetStyle();" /> <input type="button" value="修改样式" onclick="setStyle();" /> 1 <!DOCTYPE html> 2 <html lang="en"> 3 &l