- 定义
保证一个类仅有一个实例,并提供一个访问它的全局访问点 实现方式就是使用闭包,保存这个实例对象,在这个实例对象不为空的情况下,不新建实例对象,而是返回该实例
- 核心
确保只有一个实例,并提供全局访问
- 实现
假设要设置一个Person类,多次调用也仅设置一次,我们可以使用闭包缓存一个内部变量来实现这个单例
function Person(name) {
this.name = name
}
Person.prototype.getName = function () {
console.log(this.name);
}
let SinglePerson = (
function () {
var person = null
return function (name) {
if (!person) {
person = new Person(name)
}
return person
}
}
)()
SinglePerson("hzm").getName()//hzm
SinglePerson("dmt").getName()//hzm
SinglePerson("zmh").getName()//hzm
这是比较简单的做法,但是假如我们还要设置一个HR呢?就得复制一遍代码了
所以,可以改写单例内部,实现地更通用一些
function Person(name) {
this.name = name
}
Person.prototype.getName = function () {
console.log(this.name);
}
function HR(name) {
this.name = name
}
HR.prototype.getName = function () {
console.log(this.name);
}
function getSingle(fn) {
var instance = null;
return function () {
if (!instance) {
instance = fn.apply(this, arguments)
}
return instance
}
}
let getSinglePerson = getSingle(function (name) {
return new Person(name)
})
let getSingleHR = getSingle(function (name) {
return new HR(name)
})
getSinglePerson("dmt").getName()
getSinglePerson("zmh").getName()
getSingleHR("huahua").getName()
getSingleHR("lili").getName()
上面的代码每一次执行getSingle函数都会形成一个闭包,相当于一个存储一个实例对象就要建立一个闭包。优化如下:
function Person(name) {
this.name = name
}
Person.prototype.getName = function () {
console.log(this.name);
}
function HR(name) {
this.name = name
}
HR.prototype.getName = function () {
console.log(this.name);
}
let getSingle= (function () {
var instances={}
return function (fn,args) {
if (!instances[fn]) {
instances[fn] = fn.apply(this, args)
}
return instances[fn]
}
})();
let singlePerson = function (name) {
return new Person(name)
}
let singleHR = function (name) {
return new HR(name)
}
getSingle(singlePerson,["hzm"]).getName()
getSingle(singlePerson,["dmt"]).getName()
getSingle(singleHR,["hr1"]).getName()
getSingle(singleHR,["hr2"]).getName()
将所有的实例对象都存储到一个一个对象中,使用一个闭包去存储这个对象