1、只能有一个实例
2、必须自己创造唯一实例
应用场景
- 连接数据库,防止多次连接和断开
- 购物车场景
- 用户登录
- vuex
- 全局 loading 遮罩层
- 生产唯一序列号
- ......
ES6中的单例模式
// 购物车单例实例
class ShopCar {
constructor () {
// 保证只有一个实例
if (!ShopCar.instance) {
this.goodsList = [];
ShopCar.instance = this;
}
return ShopCar.instance
}
addGood (good) {
this.goodsList.push(good);
}
showGoodsList () {
console.log(this.goodsList);
}
}
var a = new ShopCar()
// 在分类页添加了一个商品
a.addGood({id: 1, name: '橘子'})
console.log(a.showGoodsList()) // 输出:[{id: 1, name: '橘子'}]
var b = new ShopCar()
// 在商品详情页添加了一个商品
b.addGood({id: 2, name: '苹果'})
console.log(b.showGoodsList()) // 输出:[{id: 1, name: '橘子'}, {id: 2, name: '苹果'}]
ES5中的单例模式
// ES5中的单例模式
var shopCar = (function () {
var goodsList = [];
var instance;
return function () { // 调用了才会创建实例
// 保证只有一个实例
if (!instance) {
// 实例
instance = {
addGood (good) {
goodsList.push(good);
},
showGoodsList () {
console.log(goodsList);
}
};
}
return instance;
};
})();
var a = shopCar()
// 在分类页添加了一个商品
a.addGood({id: 1, name: '橘子'})
a.showGoodsList() // 输出:[{id: 1, name: '橘子'}]
var b = shopCar()
// 在商品详情页添加了一个商品
b.addGood({id: 2, name: '苹果'})
b.showGoodsList() // 输出:[{id: 1, name: '橘子'}, {id: 2, name: '苹果'}]
单例模式分为两种:懒汉式和饿汉式。
懒汉式
懒汉式:使用即创建,即加载时不会创建实例,只有使用时才会创建实例
上述代码就是一个懒汉式的单例模式,具体细节不再讲解。
shopCar是一个高级函数,其返回值是一个函数。
var shopCar = (function () {....})只是加载了一个shopCar而已,并没有调用,var a = shopCar()才是正式调用,此时才会进行if判断并创建实例。
饿汉式
饿汉式:加载即创建,即加载时就创建了实例,不用是否调用,都已经存在
将上述代码稍微改写一下
// ES5中的单例模式
var shopCar = (function () {
var goodsList = [];
var instance = { // 加载即创建实例
addGood (good) {
goodsList.push(good);
},
showGoodsList () {
console.log(goodsList);
}
};
// 调用的时候直接返回实例,保证只有一个实例
return function () {
return instance;
};
})();
var a = shopCar()
// 在分类页添加了一个商品
a.addGood({id: 1, name: '橘子'})
a.showGoodsList() // 输出:[{id: 1, name: '橘子'}]
var b = shopCar()
// 在商品详情页添加了一个商品
b.addGood({id: 2, name: '苹果'})
b.showGoodsList() // 输出:[{id: 1, name: '橘子'}, {id: 2, name: '苹果'}]
优点
- 确保了只有一个实例
- 因为只有唯一实例,所以节省了系统资源,记住创建和销毁也需要浪费内存资源
- 避免了对资源的多重占用,比如数据库的连接
- 资源共享
更多相关文档,请见:
线上地址 【前端橘子君】
GitHub仓库【前端橘子君】