- 一个构造函数, 在实例化对象时, 判断是否为第一次实例化
- 是第一次创建一个实例化对象, 然后返回
- 不是第一次想办法拿到第一次的实例化对象, 然后返回
- 拿一个变量, 初始值给一个null
- 在实例化对象时, 第一次实例化, 直接将实例化赋值给变量, 然后将变量返回
- 后续再实例化的时候, 直接返回刚才的变量
- class Dialog {
- constructor(title) {
- console.log('创建一个弹出框插入到页面中, 类型为: ')
- this.title = title
- }
- }
-
- let instance = null
- function newDialog(type) {
-
- if (instance === null) {
- instance = new Dialog(type)
- }
-
- return instance
- }
-
- const n1 = newDialog('警告')
- console.log(n1)
-
- const n2 = newDialog('文本')
- console.log(n2)
1. 全局多了一个变量instance
2. 传递多个参数 ,无法生效
3. 构造函数的类, 和实际使用创建的函数, 不是一个名字
- class Dialog {
- constructor(title) {
- console.log('创建一个弹出框插入到页面中, 类型为: ')
- this.title = title
- }
- }
-
- function fn(type) {
- let instance = null
- return function newDialog() {
-
- if (instance === null) {
- instance = new Dialog(type)
- }
-
- return instance
- }
- }
-
- const n1 = fn('警告')
- const res = n1()
- console.log(res)
- class Dialog {
- constructor(title) {
- console.log('创建一个弹出框插入到页面中, 类型为: ')
- this.title = title
- }
- }
-
- // 利用自执行函数 进一步优化
- const newDialog = (function fn() {
- let instance = null
- return function inner(type) {
-
- if (instance === null) {
- instance = new Dialog(type)
- }
-
- return instance
- }
- })()
- const n1 = newDialog('警告')
- console.log(n1)
-
- const n2 = newDialog('文本')
- console.log(n2)
- class Dialog {
- constructor() {
- console.log('创建一个弹出框插入到页面中, 类型为: ')
- this.title = ''
- }
- // 每次需要给title赋值, 直接调用这个方法即可
- init(title) {
- this.title = title
- console.log('当前title的值为: ', title)
- }
- }
- const newDialog = (function fn() {
- let instance = null
- return function inner(type) {
-
- if (instance === null) {
- instance = new Dialog()
- }
-
- instance.init(type)
-
- return instance
- }
- })()
-
- const n1 = newDialog('警告')
- console.log(n1)
-
- const n2 = newDialog('文本')
- console.log(n2)
- const Dialog = (function fn() {
- let instance = null
-
- class Dialog {
- constructor() {
- console.log('创建一个弹出框插入到页面中, 类型为: ')
- this.title = ''
- }
- // 每次需要给title赋值, 直接调用这个方法即可
- init(title) {
- this.title = title
- console.log('当前title的值为: ', title)
- }
- }
-
- return function inner(type) {
- // 1. 自动帮我们创建一个对象, 自动帮我们把函数内部的this指向这个新建对象
- // 2. 手动往对象上添加属性
- // 3. 自动返回一个对象
-
- // 4. 构造函数内部不要写return, 返回一个基本数据类型, 写了和没写一样,
- // 如果返回一个引用数据类型, 写了构造函数就没用了
-
- if (instance === null) {
- instance = new Dialog()
- }
-
- instance.init(type)
-
- return instance
- }
- })()
-
- // // 单例模式, 一般不建议写 new
- const n1 = Dialog('警告')
- const n2 = Dialog('文本')
- const n3 = Dialog('红色警告')
-
- console.log(n1)
- console.log(n2)
- console.log(n3)
-
- console.log(n1 === n2)
- console.log(n2 === n3)
- console.log(n1 === n3)
- 核心: 减少过多的 if...else...
- 需求: 去购物, 购物总价1987 折扣: 8折 7折 300-30 500-50
- 策略模式处理: 有一个数据结构,内部存储着各种折扣对应的计算总价方式
- // 70% '300-30' '500-50' 60% 75%
- let type = '80%';
- let total = 1987;
- if (type === '80%') {
- } else if (type === '70%') {
- } else if (type === '300-30') {
- } else if (type === '500-50') {
- } else if (type === '60%') {
- } else if (type === '75%') {
- }
- const price = (function(){
- let PriceList = {
- // '80%': (total) =>{}
- '80%': total =>total * 0.8,
- '70%': total =>total * 0.7,
-
- }
- return function inner(type, total){
- // console.log('inner函数开始执行,计算商品总价');
- // console.log(type);
- // console.log(PriceList[type]);
- // console.log(PriceList[type](total));
- return PriceList[type](total)
- }
- })()
-
- let newPrice1 = price('80%', 1000);
- let newPrice2 = price('70%', 1000);
- console.log(newPrice1);
- console.log(newPrice2);
- const price = (function(){
- let PriceList = {
- // '80%': (total) =>{}
- '80%': total =>total * 0.8,
- '70%': total =>total * 0.7,
- }
-
- return function inner(type, total){
- // 新增其他折扣时
- inner.add = (key, value) =>{
- PriceList[key] = value;
- }
-
- // 只传递一个参数时
- inner.sub = (key) =>{
- PriceList[key] = null
- }
-
- // 打印PriceList列表时
- inner.GetList = () =>{
- return PriceList
- }
- return PriceList[type](total)
- }
- })()
-
- let newPrice1 = price('80%', 1000);
- let newPrice2 = price('70%', 1000);
- price.add('60%', total =>total * 0.6);
- let list = price.GetList();
- console.log(newPrice1);
- console.log(newPrice2);
- console.dir(price);
- 这个模式适用于大型项目的封装
- 自行搜索: Vue2 响应式原理
- 除了 发布订阅模式, 还有一种叫观察者模式,这两个开发模式, 特别相似
- class observer {
- constructor(name) {
- // 模拟一个店员(不重要)
- this.name = name
-
- // 店员的记录手册
- this.message = {}
- }
-
- // 原型
- add(type, fn) {
- if (this.message[type] === undefined) {
- this.message[type] = []
- }
-
- this.message[type].push(fn)
- }
-
- tri(type) {
- // 调用这个方法, 通知对应的 人员 来购买
- // console.log(type)
- // console.log(this.message[type])
- this.message[type].forEach(item => {
- // console.log(item)
- item()
- })
- }
-
- remove(type, fn) {
- // console.log(type, fn)
- // console.log(this.message[type], fn)
- this.message[type] = this.message[type].filter(item => item !== fn)
- }
- }
-
- const res = new observer('小方')
- console.log('初始数据: ', res)
-
- const fnA = () => {
- console.log('我是张三, 我想购买这本书')
- }
- const fnB = () => {
- console.log('我是李四, 我想购买这本书')
- }
- const fnC = () => {
- console.log('我是王五, 我想购买这本书')
- }
-
- // 新增(留下联系方式)
- res.add('JS从入门到入土', fnA)
- res.add('JS从入门到入土', fnB)
- res.add('颈椎病的预防', fnC)
-
- // 书本到了, 通知对应的预约者, 前来购买
- res.tri('颈椎病的预防')
-
- // 某人, 取消预约一本书
- res.remove('JS从入门到入土', fnA)
-
- console.log(res)