- 组合模式介绍
- 实现思想
- 组合模式代码
- 组合模式的简单应用场景
- 三、观察者模式
- 观察者模式介绍
- 观察者模式介绍实现思想
- 观察者模式代码
- 四、发布/订阅模式
- 发布/订阅模式介绍及实现思想
- 发布/订阅模式代码
一、单例模式
我们都知道一个构造函数可以使用 new 关键字来创造出若干的实例。并且每个实例都是不相同的。都是不同的地址,比较两个生成的实例时比较的是存储地址,因此每个实例都有不同的存储空间,两者比较值为false
。
function Person(){ this.name=‘小明’ } var p1=new Person() var p2=new Person() console.log(p1===p2)//false
单例模式介绍
使用构造函数实例化的时候,不管实例化多少回,都实例化出同一个对象
- 一个构造函数一生只能 new 出一个对象
- 当我们使用构造函数,每一次 new 出来的对象 属性/功能/方法 完全一样 的时候,我们把他设计成单例模式
核心代码如下
//核心代码 //一个构造函数 function Person() { this.name = ‘Jack’ } //全局变量 instance var instance = null function singleton() { if (instance === null) { instance = new Person() } return instance } //这是singleton函数第一次调用,这时全局变量instance=null //因此,instance=new Person() //全局变量instance的值是Person构造函数的一个实例(将其命名为 实例 001) //p1 为 实例001 var p1=new singleton() //这是singleton函数第二次调用,这时全局变量instance 为 实例001 //instance的值不为空 ,因此直接返回 全局变量instance原来的值(实例001) //p2 为 实例001 var p2=new singleton() //p1 p2 的值都为实例001 得到的都是同一个对象 因此值为true console.log(p1===p2)//true //之后不管再实例化多少回,过程都与第二次调用singleton一致
注意
var p1 = new singleton()
这里的new关键字
并不是实例一个对象,因为p1
就是singleton函数
的返回值instance
。构造函数如果返回一个复杂数据类型,那么最后得到的值就是那个复杂数据。这里的实例是构造函数Person
的实例。用new关键字只是表示,我们每一次都实例了一个一模一样的对象。
将代码进行优化
- 这一步我们需要了解JS的闭包以及对构造函数有较为深刻的理解。
- 闭包的条件
- 有一个 A 函数,再 A 函数内部返回一个 B 函数
- 再 A 函数外部有变量引用这个 B 函数
- B 函数内部访问着 A 函数内部的私有变量
- 以上三个条件缺一不可
- 形成闭包后,函数的执行空间不会被销毁,会一直存在。里面的变量也就不会被销毁。
- 构造函数
- 一个构造函数可以使用 new 关键字来创造出若干的实例。
- 每一个实例都可以使用这个构造函数的属性和方法。
//外部的Person并不是生成实例的构造函数 new Person 与 Person()得到的值都一样 //最后的结果写成 p = new Person() 是因为p 确实是构造函数的实例, //不过这个构造函数是内部的Person //也是因为这样写代码更美观,更直观的看出是用一个构造函数创造相同的实例。 //外部的Person 是一个自执行函数 (function () {})() // 执行后立马的到返回值 => 实例对象 var Person = (function () { //这一部分就是我们的核心代码 function Person() {} var instance = null //函数返回值 返回一个函数 函数的值是一个实例 return function () { //利用 三木运算符 简化代码 return !instance ? instance = new Person() : instance } })() //自执行函数 的执行空间不会销毁,形成了一个闭包空间 //执行空间不被销毁 那么instance 这个变量也就不会销毁 //第一次执行得到的是一个Person的实例 //之后的每一次执行,得到的都是第一次的那个实例 p1=new Person() p2=new Person() console.log(p1==p2)//true
单例模式的简单应用场景
- 网站的弹出层
alert()
或者右下角的广告页面 - 一个网站不可能只弹出一次这个界面,不能每次弹出就创建一个
- 每次弹出的都是之前创造好的,只是内容发生变化
二、组合模式
组合模式介绍
- 举一个简单的例子,就像家里每个电器都有单独的开关,而组合模式就是设置一个
总开关
,这个开关可以控制家中所有电器的开关,这就是组合模式
。
实现思想
- 先定义控制
不同电器的开关
,也就是一个个构造函数
,每一个构造函数都有一个启动方法
- 每一个构造函数的实例就是一个个电器开关
- 再定义一个
总开关
,一个构造函数
,有一个方法可以启动所有构造函数
的, - 这时,需要一个承载所有
构造函数实例的数组
- 总开关构造函数需要一个方法, 向数组里面添加内容
- 总开关构造函数需要一个方法, 能把数组里面的所有内容启动了
组合模式代码
// 一个构造函数的启动方式 控制玩的开关 class Play { constructor () {} // 这个构造函数的启动方法 init () { console.log(‘开始玩游戏’) this.a() this.b() this.c() } a () {} b () {} c () {} } // 第二个构造函数 控制吃的开关 class Eat { constructor () {} init () { console.log(‘去吃饭’) } } //第三个构造函数 控制睡觉的开关 class Sleep { constructor () {} init () { console.log(‘去睡觉’) } } // 组合模式的代码 总开关 class Compose { constructor () { // 用来承载每一个实例的数组 this.composeArr = [] } // 向数组里面添加内容 add (instance) { this.composeArr.push(instance) } // 把数组里面的每一个内容调用了 init () { console.log(‘总开关启动了’) this.composeArr.forEach(item => item.init()) } } // c 就是一个总开关 var c = new Compose() // 每一次执行 add 方法就是向总开关上添加内容 使得总开关 可以控制 其他开关 c.add(new Play()) c.add(new Eat()) c.add(new Sleep()) // 只要我的总开关一启动 // 里面的每一个构造函数就同时都启动了 c.init() console.log©