js趣玩:js单例

73 浏览发布于 作者 zouyang (欢迎转载-请注明出处链接)留下评论分享按钮

一、

1、让全局都只能有一个实例,就是单例了。。
那么 要实现单例,肯定是需要判断的,每次实例化时,就需要判断是否已经实例化过了,如果 true,那么就返回之前实例化过的,就是单例了。

2、如何判断呢,那我们在实例化的时候肯定得有一个 内部的变量 供我们判断,这个变量存储着实例化过的类。如果这个变量为undefined,则走实例化的操作,并将实例化后的对象赋值给这个内部变量。

function singleObj( fn ){
    var _ret;
    return function(){
        return _ret || ( _ret = fn.apply( this, arguments) );
    }
}


var singleBox = singleObj(function(){
    return {
        boxName:"xx"
    }
});

var singleBox1 = singleBox();
var singleBox2 = singleBox();

console.log( singleBox1 );
console.log( singleBox2 );
console.log( singleBox1 === singleBox2 ); //true

二、当然,js 内本来就具备一种很方便的单例模式:

用全局变量来实现:var a = {};

当用这种方式创建对象 a 时,对象 a 确实是独一无二的。如果 a 变量被声明在全局作用域下,则我们可以在代码中的任何位置使用这个变量,全局变量提供给全局访问是理所当然的。这样就满足了单例模式的条件。

为了避免全局变量造成的污染,可以配合使用 命名空间、闭包封装私有变量 这2种方式:

1)命名空间

var namespace_a = {
    name:function() {
      //……
    },
    age:function() {
      //……
    }
}

name、age 都定义为 namespace_a 的属性,减少变量污染全局作用域。

2)闭包封装私有变量:

//这种方法把一些变量封装在闭包的内部,只暴露一些接口跟外界通信:
var user = (function(){ 
     var _name = 'Lee'; 
     return { 
         getName: function(){ 
            return _name; 
         } 
     } 
 })(); 

我们用下划线来约定私有变量__name 和__age,它们被封装在闭包产生的作用域中,外部是访问不到这两个变量的,这就避免了对全局的命令污染。

(完)

想要打赏,请点击这里

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注