第四章、单例模式
单例模式的核心:唯一的实例,在全局能访问到
全局变量不是单例模式,但会把全局变量当作单例模式使用。
减少全局模式的使用方法:
1.使用命名空间:
js
let A = {
add(){}
}
A.add()
2.使用闭包封装私有变量
把一些变量封装到闭包内部,只暴露一些接口
js
const user = (function() {
var name = 'a',
age = 29
return {
getUserInfo : function() {
return name+age;
}
}
})()
4.1惰性单例
在需要的时候才去创对象实例
应用场景:弹窗、购物车等
javascript
let timeTool = (function() {
let _instance = null;
function init() {
//私有变量
let now = new Date();
//共有属性方法
let name = '时间处理工具';
this.getTime = function() {
return now.toTimeString();
}
}
return function() {
if(!_instance) {
_instance = new init();
}
return _instance;
}
})();
let instance1 = timeTool();
let instance2 = timeTool();
console.log(instance1 === instance2); //true
上面的timeTool
实际上是一个函数,_instance
作为实例对象最开始赋值为null
,init
函数是其构造函数,用于实例化对象,立即执行函数返回的是匿名函数用于判断实例是否创建,只有当调用timeTool()
时进行实例的实例化,这就是惰性单例的应用,不在js加载时就进行实例化创建, 而是在需要的时候再进行单例的创建。 如果再次调用, 那么返回的永远是第一次实例化后的实例对象。
4.2扩展 ES6中创建单例模式
import export就是单例模式
使用ES6的语法将constructor
改写为单例模式的构造器。
javascript
class SingletonApple {
constructor(name, creator, products) {
//首次使用构造器实例
if (!SingletonApple.instance) {
this.name = name;
this.creator = creator;
this.products = products;
//将this挂载到SingletonApple这个类的instance属性上
SingletonApple.instance = this;
}
return SingletonApple.instance;
}
}
/*
constructor(name, creator, products) {
this.name = name;
this.creator = creator;
this.products = products;
}
//静态方法
static getInstance(name, creator, products) {
if(!this.instance) {
this.instance = new SingletonApple(name, creator, products);
}
return this.instance;
}
}
*/
let appleCompany = new SingletonApple('苹果公司', '乔布斯', ['iPhone', 'iMac', 'iPad', 'iPod']);
let copyApple = new SingletonApple('苹果公司', '阿辉', ['iPhone', 'iMac', 'iPad', 'iPod']);
console.log(appleCompany === copyApple); //true