js实现单例模式,经常使用两种方法,一种是使用构造函数的静态属性中缓存该实例,另一种是将实例包装在闭包中。

第一种实现方式:

//静态属性中单例模式
function Universe() {
if (typeof Universe.instance === "object") {
return Universe.instance;
}
//正常运行
this.start_time = 0;
this.bang = "Big"; //缓存
Universe.instance = this;
//隐式返回
//return this;
} var uni = new Universe();
var uni2 = new Universe();
console.log(uni === uni2 ); //true

第二种实现方式:

/闭包中实现单例模式
function Universe(){
//缓存实例
var instance = this;
//正常进行
this.start_time = 0;
this.bang = "Big";
//重写该构造函数
Universe = function(){
return instance;
}
//隐式返回
//return this;
}
var uni = new Universe();
var uni2 = new Universe();
console.log(uni == uni2); //true

上面实现单例模式有个缺点,就是重写构造函数,会丢失所有在初始化和重定义时刻之间添加到它里面的属性,如下

//test
Universe.prototype.nothing = true;
var uni = new Universe();
//在创建初始化对象之后,再次向该原型添加属性
Universe.prototype.something = true;
var uni2 = new Universe(); console.log(uni.nothing); //true
console.log(uni2.nothing); //true
console.log(uni2.something); //undefined
console.log(uni2.something); //undefined
console.log(uni.constructor.name); //Universe
console.log(uni.constructor === Universe); //false

其中uni.constructor仍然指向了原始的构造函数。

如果需要使原型和构造函数指针按照预期的那样运行,可以向下面一样改写代码

//如果需要使原型和构造函数指针能够按照预期那样运行,改写如下
function Universe() {
//缓存实例
var instance;
//重写构造函数
Universe = function Universe() {
return instance;
};
//保留原型属性
Universe.prototype = this;
//实例
instance = new Universe(); //重置构造函数指针
instance.constructor = Universe;
//功能实现
instance.start_time = 0;
instance.bang = "Big"; return instance;
}
//test
Universe.prototype.nothing = true;
var uni = new Universe();
//在创建初始化对象之后,再次向该原型添加属性
Universe.prototype.something = true;
var uni2 = new Universe(); console.log(uni.nothing); //true
console.log(uni2.nothing); //true
console.log(uni2.something); //true
console.log(uni2.something); //true
console.log(uni.constructor.name); //Universe
console.log(uni.constructor === Universe); //true

另一种解决方案是将构造函数和实例包装在即使函数中。

var Universe;
(function(){
var instance;
Universe = function Universe(){
if(instance){
return instance;
}
instance = this; //所有的功能
this.start_time = 0;
this.bang = "BIg";
}
}());

js单例模式的更多相关文章

  1. 浅谈js单例模式

    单例模式就是在系统中保存一个实例,就是一个全局变量,在团队开发中,为了实现一些相似的功能,比如不同页面之间的表单验证,可能需求是不一样的,但是呢命名可能一样,这时就会产生冲突,这时候单例模式就能很好的 ...

  2. JS单例模式在工作中的使用

    为了尽可能的减少全局变量的污染,在写js的时候可以采用单例模式,形式如下: 比如有一个js叫demo.js,那么我们可以在js里这样写: var demo = {} 这样做的目的是将整个js当成一个对 ...

  3. js单例模式详解实例

    这篇文章主要介绍了什么是单例单例模式.使用场景,提供了3个示例给大家参考 什么是单例? 单例要求一个类有且只有一个实例,提供一个全局的访问点.因此它要绕过常规的控制器,使其只能有一个实例,供使用者使用 ...

  4. JS 单例模式

    <parctical common lisp>的作者曾说,如果你需要一种模式,那一定是哪里出了问题.他所说的问题是指因为语言的天生缺陷,不得不去寻求和总结一种通用的解决方案. 不管是弱类型 ...

  5. js 单例模式笔记

    单例指一个类只有一个实例,这个类自行创建这个实例. 利用对象字面量直接生成一个单例: var singleton = { prop: 1, method: function(){ console.lo ...

  6. js 单例模式的实现方式----闭包和构造函数内部判断

    闭包: var singleton = function( fn ){ var result; return function(){ return result || ( result = fn .a ...

  7. js原生设计模式——8单例模式之简约版属性样式方法库

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  8. 收藏的js学习小例子

    1.js模拟java里的Map function Map(){ var obj = {} ; this.put = function(key , value){ obj[key] = value ; ...

  9. JS学习笔记3_函数表达式

    1.函数表达式与函数声明的区别 函数声明有“提升”(hoisting)的特性,而函数表达式没有.也就是说,函数声明会在加载代码时被预先加载到context中,而函数表达式只有在执行表达式语句时才会被加 ...

随机推荐

  1. 各种位置和高度计算:.position()、.offset()、.outerHeight()、.scrollTop、.scrollHeight、.clientHeight

    1..position()和.offset() jquery的.position()获取相对于最近的position为relative或absolute的父元素的偏移,返回.position().le ...

  2. [python]百度语音rest api

    百度语音识别提供的api范例只有java, c, php. 如果使用Python, 需要注意: 语音文件长度是指bytes大小 可以通过len(file.read())获得 使用requests.po ...

  3. Swift--访问级别-备

    访问级别: Swift提供了3种不同访问级别,对应的访问修饰符为:public.internal和private.这些访问修饰符可以修饰类.结构体.枚举等面向对象的类型,还可以修饰变量.常量.下标.元 ...

  4. 用windows live writer写博客

    用windows live writer写博客了,目前不支持writer的博客,暂时放弃,这正是我用writer写的第一篇内容. 如有知道怎么用weiter配置:凤凰博客.搜狐博客.QQ空间.百度空间 ...

  5. LeetCode_Best Time to Buy and Sell Stock III

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  6. JavaScript对象基础知识

    1.对象所包含的元素一组包含数据的属性.如人的名字.书的价格和手机型号等.允许对属性中所包含的数据进行操作的方法. 2.引用对象的途径一个对象真正地被使用,可以采用以下几种方式.引用Javascrip ...

  7. B树叶子节点split

    一.B-Tree索引的分裂 1. 创建测试表 SQL> create table split_tab (id number, name varchar2(100)); 表已创建. SQL> ...

  8. BZOJ2751: [HAOI2012]容易题(easy)

    2751: [HAOI2012]容易题(easy) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 872  Solved: 377[Submit][S ...

  9. android真机调试

    android开发可以使用google那个自带的模拟器来调试,不过那个模拟器启动实在太慢,太耗时了,不过,如果我们有android手机的话,我们可以直接在手机上调试,这样的话,速度就很快: 具体步骤如 ...

  10. Android——LayoutInflater详解

    在实际工作中,事先写好的布局文件往往不能满足我们的需求,有时会根据情况在代码中自定义控件,这就需要用到LayoutInflater. LayoutInflater在Android中是"扩展& ...