1.单例模式解释
单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。在JavaScript里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。
2.应用场景举例
登录页
购物车
vuex
全局loading遮罩
......
3.代码解释
1.通过闭包和立即执行函数实现
var singletonPatten = (function() {
// 单例构造函数
function singleton(arg) {
var arg = arg || {}
this.x = arg.x || 1
this.y = arg.y || 1
}
// 单例实例容器
var instance
return function(arg) {
if(!instance) {
instance = new singleton(arg)
}
return instance
}
}())
var singletonTest1 = singletonPatten({x: 2, y: 7})
var singletonTest2 = singletonPatten()
singleton1.z = 3
console.log(singletonTest1 === singletonTest2) //true
console.log(singletonTest2.x) // 2
console.log(singletonTest2.z) // 3
第一次取实例时, 把singleton实例存到instance中,第二次实例已经存在直接返回instance,所以第一次获得的实例和第二次获得的实例是相同的。
2.通过构造函数实现
function Singleton(arg) {
//实例是否已存在
if(typeof Singleton.instance === 'object') {
return Singleton.instance
}
var arg = arg || {}
this.x = arg.x || 1
this.y = arg.y || 1
//缓存实例
Singleton.instance = this
}
var singleton1 = new Singleton({x: 2, y: 2})
var singleton2 = new Singleton()
singleton1.z = 3
console.log(singleton1 === singleton2) //true
console.log(singleton2.x) //2
console.log(singleton2.z) //3
获得构造函数实例前先判断instance是否存在,存在则直接返回,否则将构造函数中的this进行缓存,下次取实例可以直接返回第一次获得的实例
3.构造函数重构实现
function Singleton(arg) {
var arg = arg || {}
//缓存实例
var instance = this
this.x = arg.x || 1
this.y = arg.y || 1
//重构构造函数
Singleton = function() {
return instance
}
}
var singleton1 = new Singleton({x: 2, y: 2})
var singleton2 = new Singleton()
singleton1.z = 3
console.log(singleton1 === singleton2) //true
console.log(singleton2.x) //2
console.log(singleton2.z) //3
第一次获得实例先将实例缓存到instance中,然后就构造函数进行一个重构,重构后的构造函数直接返回缓存的实例instanceof,第二次获得后便直接返回直接缓存的实例
4.通过class类实现
class Singleton {
constructor(arg) {
var arg = arg || {}
this.x = arg.x || 1
this.y = arg.y || 1
}
static getInstance(arg) {
if(!Singleton.instance) {
Singleton.instance = new Singleton(arg)
}
return Singleton.instance
}
}
var singleton1 = Singleton.getInstance({x: 2, y: 2})
var singleton2 = Singleton.getInstance()
singleton1.z = 3
console.log(singleton1 === singleton2) //true
console.log(singleton2.x) //2
console.log(singleton2.z) //3
静态方法getInstance获取类的实例,先判断instance上面是否缓存实例,没有缓存,如果存在直接返回。
4.实际应用场景
实现一个全局loading遮罩框
class Loading {
constructor() {
this.visile = false
}
show() {
if(this.visile) {
console.log('已经展示')
return true
}
this.visile = true
}
hide() {
if(!this.visile) {
console.log('已经隐藏')
return true
}
this.visile = false
}
static getLoadingMask() {
if(!Loading.instance) {
Loading.instance = new Loading()
}
return Loading.instance
}
}
上述代码,定义了一个loading遮罩的类,有两个实例方法,show和hide,还有一个静态类getInstanceMask
当两处地方需要获得loading遮罩实例进行操作
var loading1 = Loading.getLoadingMask()
var loading2 = Loading.getLoadingMask()
console.log(loading1 === loading2) //true
loading1.show()
loading1.hide()
loading1.show()
loading2.show() //已经展示
loading2.hide()
loading2.hide() //已经隐藏
当对loading1和loading2执行show方法,第二次执行show会报已经展示,表示是同一个laoding遮罩实例
这样就实现了一个单例模式的实际应用场景。
其他的如基于vue的vuex就是最典型的单例模式,因为它的全局状态管理器,只能存在一个,不能多个。
单例模式实际为了节省资源而存在的一种模式,也是很常见的一种模式之一。
单例模式是我们开发中一个非常典型的设计模式,js单例模式要保证全局只生成唯一实例,提供一个单一的访问入口,单例的对象不同于静态类,我们可以延迟单例对象的初始化,通常这种情况发生在我们需要等待加载创建单例的依赖。
工厂模式下的对象我们不能识别它的类型,由于typeof返回的都是object类型,不知道它是那个对象的实例。另外每次造人时都要创建一个独立的person的对象,会造成代码臃肿的情况。
建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象
主要涉及知识点: HTML与XHTML,HTML与XHTML的区别,DOCTYPE与DTD的概念,DTD的分类以及DOCTYPE的声明方式,标准模式(Standard Mode)和兼容模式(Quircks Mode),标准模式(Standard Mode)和兼容模式(Quircks Mode)的区别
JavaScript中常见的四种设计模式:工厂模式、单例模式、沙箱模式、发布者订阅模式
javascript 策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。 策略模式利用组合,委托等技术和思想,有效的避免很多if条件语句,策略模式提供了开放-封闭原则,使代码更容易理解和扩展, 策略模式中的代码可以复用。
javascript观察者模式又叫发布订阅模式,观察者模式的好处:js观察者模式支持简单的广播通信,自动通知所有已经订阅过的对象。存在一种动态关联,增加了灵活性。目标对象与观察者之间的抽象耦合关系能够单独扩展以及重用。
熟悉 Vue 的都知道 方法methods、计算属性computed、观察者watcher 在 Vue 中有着非常重要的作用,有些时候我们实现一个功能的时候可以使用它们中任何一个都是可以的
我觉得聊一下我爱用的 JavaScript 设计模式应该很有意思。我是一步一步才定下来的,经过一段时间从各种来源吸收和适应直到达到一个能提供我所需的灵活性的模式。让我给你看看概览,然后再来看它是怎么形成的
在围绕设计模式的话题中,工厂这个词频繁出现,从 简单工厂 模式到 工厂方法 模式,再到 抽象工厂 模式。工厂名称含义是制造产品的工业场所,应用在面向对象中,顺理成章地成为了比较典型的创建型模式
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!