你的位置:首页 > Java教程

[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);  }};




内蒙古旅游团购优惠内蒙古旅游线路报价内蒙古旅游指南攻略大全内蒙古旅游住哪里比较方便内蒙古旅游住宿攻略深圳麦鲁小城好玩吗?麦鲁小城有什么好玩的? 童话般的世界 吉林雾凇岛 深圳麦鲁小城团购门票多少钱?麦鲁小城团购价格? 深圳麦鲁小城游玩攻略?麦鲁小城开放时间? 广州石头记矿物园地址?石头记矿物园怎样去? 广州石头记矿物园怎么样?石头记矿物园里面有什么? 花都石头记矿物园景区电话?石头记矿物园门票预订? 珠海市荷包岛的酒店有哪些?荷包岛有吃饭的地方吗? 颜公河漂流景点电话多少?黄山颜公河漂流咨询电话? 颜公河漂流怎么样?黄山颜公河漂流好不好玩? 黄山颜公河漂流时间?休宁颜公河漂流开漂了吗? 趵突泉公园到大观园需要多长时间?趵突泉离大观园多远? 北京圣诞情侣餐厅 南方女孩冬天去北京旅游要注意什么? 2015年世界末日后有哪些明星来北京开演唱会? 北京本地女孩或去北京的南方女孩冬天是如何保养皮肤的? 554-2231-211 Datasheet 554-2231-211 Datasheet 554-2231-311 Datasheet 554-2231-311 Datasheet 554-2231-411 Datasheet 554-2231-411 Datasheet 扬州去港澳游 扬州去港澳游 扬州去港澳游 到黑龙江跟团去香港旅游 到黑龙江跟团去香港旅游 到黑龙江跟团去香港旅游 四平参团去港澳旅游 四平参团去港澳旅游 四平参团去港澳旅游