一、
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,它们被封装在闭包产生的作用域中,外部是访问不到这两个变量的,这就避免了对全局的命令污染。
(完)
想要打赏,请点击这里