JS实现单例模式的6种⽅案汇总
前⾔
今天在复习设计模式中的-创建型模式,发现JS实现单例模式的⽅案有很多种,稍加总结了⼀下,列出了如下的6种⽅式与⼤家分享
⼤体上将内容分为了ES5(Function)与ES6(Class)实现两种部分
单例模式的概念
单例模式就是在系统中保存⼀个实例,就是⼀个全局变量,在团队开发中,为了实现⼀些相似的功能,⽐如不同页⾯之间的表单验证,可能需求是不⼀样的,但是呢命名可能⼀样,这时就会产⽣冲突,这时候单例模式就能很好的解决这个问题。
⼀个实例只⽣产⼀次
保证⼀个类仅有⼀个实例,并提供⼀个访问它的全局访问点
说说它的优点:
1,单例模式声明⼀个命名空间,它⽣成⼀个唯⼀的全局变量,⼀个命名空间,可以⽤声明对象的⽅式来声明:var mapleTao={ name:"mapleTao",init:function(){console.log(this.name)}};
有⽊有发现这个和对象有点类似呢,其实name,init是它的属性,通过mapleTao.name就获取它name的值,通过mapleTao.init()就可以调⽤init⽅法,这样在哎处理多需求页⾯,多⼈开发时就能很好的解决命名冲突的问题,以及可以更好的维护代码,更好的控制代码。
2,单例模式在全局中只声明⼀个变量,⼤家都知道在js中,假设你写了⼀个⽅法,如 function aa(){},这样就会在window中⽣成⼀个叫aa的变量,当实现⼀个功能时,在代码封装中,会创建好多函数,好多function,这样就会在window中创建好多变量,会占⽤更多的内存单元,全局变量的作⽤域很⼴,在众多处理函数中都可能改变,这样当出现bug时不容易快速到,⽽通过单例模式创建的对象变量中可以更快速的到问题,从⽽解决,这⼤⼤减少的问题修复的时间以及系统加载的时间。
3.在实现同⼀个功能的地⽅⽐通过new新创建对象对内存对资源的占⽤更据优势。
⽅式1
利⽤instanceof判断是否使⽤new关键字调⽤函数进⾏对象的实例化
function User() {
if (!(this instanceof User)) {
return
}
if (!User._instance) {
this.name = '⽆名'
User._instance = this
}
return User._instance
}
const u1 = new User()
const u2 = new User()
console.log(u1===u2);// true
⽅式2
在函数上直接添加⽅法属性调⽤⽣成实例
function User(){
this.name = '⽆名'
}
if(!User._instance){
User._instance = new User()
}
return User._instance
}
const u1 = Instance()
const u2 = Instance()
console.log(u1===u2);
⽅式3
使⽤闭包,改进⽅式2
function User() {
this.name = '⽆名'
}
var instance
return function () {
if (!instance) {
instance = new User()
}
return instance
}
})()
const u1 = Instance()
单例模式的几种实现方式const u2 = Instance()
console.log(u1 === u2);
⽅式4
使⽤包装对象结合闭包的形式实现
const User = (function () {
function _user() {
this.name = 'xm'
}
return function () {
if (!_user.instance) {
_user.instance = new _user()
}
return _user.instance
}
})()
const u1 = new User()
const u2 = new User()
console.log(u1 === u2); // true
当然这⾥可以将闭包部分的代码单独封装为⼀个函数
在频繁使⽤到单例的情况下,推荐使⽤类似此⽅法的⽅案,当然内部实现可以采⽤上述任意⼀种function SingleWrapper(cons) {
// 排除⾮函数与箭头函数
if (!(cons instanceof Function) || !cons.prototype) {
throw new Error('不是合法的构造函数')
}
var instance
return function () {
if (!instance) {
instance = new cons()
}
return instance
}
}
function User(){
this.name = 'xm'
}
const SingleUser = SingleWrapper(User)
const u1 = new SingleUser()
const u2 = new SingleUser()
console.log(u1 === u2);
⽅式5
在构造函数中利⽤new.target判断是否使⽤new关键字
class User{
constructor(){
if(new.target !== User){
return
}
if(!User._instance){
this.name = 'xm'
User._instance = this
}
return User._instance
}
}
const u1 = new User()
const u2 = new User()
console.log(u1 === u2);
⽅式6
使⽤static静态⽅法
class User {
constructor() {
this.name = 'xm'
}
static getInstance() {
if (!User._instance) {
User._instance = new User()
}
return User._instance
}
}
const u1 = Instance()
const u2 = Instance()
console.log(u1 === u2);
总结
到此这篇关于JS实现单例模式的⽂章就介绍到这了,更多相关JS单例模式内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论