jquery(一)

55 阅读6分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第13天,点击查看活动详情

首先我们在讲 jQuery 的时候穿插一下 Event Loop

事件轮询(客户端 Event Loop)

JS 代码的同步异步执行机制

调用栈 : 专门用来执行代码的栈

        LIFO: last in first out

队列 : 异步任务排队的位置

        事件队列: Event queue

        微任务队列: Microsoft Queue

          Promise.then()

        宏任务队列: Macrosoft Queue

        整体代码

         定时器

        FIFO: first in first out

WEB APIs : 提供异步机制的

        分配任务到哪一个队列

        会在每一次调用栈空的时候进行 计时 和 分配

Event Loop

        轮流询问 宏任务队列 和 微任务队列

        从 宏任务 开始, 一个宏任务, 清空一次微任务队列

          再一个宏任务, 清空一次微任务队列

          直到微任务队列清空完毕, 再次访问宏任务队列也没有任务的时候

EventLoop 暂停

设计模式

        书写代码的方式

        目的是解决特定问题给出的简洁而优化的解决方案

        之前接触过设计模式

          懒惰模式、沙箱模式

        另外的四个设计模式

   单例模式

单: 单一, 一个

        例: 实例

        一个构造函数一生只能有一个实例

        不管你 new 多少次, 都是一个实例

    应用:

        自定义弹出层

          结构: div > xxx, 默认隐藏, 在一定条件下显示

          实现: 每次显示都是一个新的 div 还是一个 div 来回来去的显示

这里有两个问题需要注意

        1. 书写代码的时候和 构造函数已经没有关系

        2. new 关键字没有了

function Person() {    
this.name = 'Jack'    }
// 加入单例模式核心代码   
let instance = null   
function singleTon() {    
if (!instance) instance = new Person() 
return instance    
}
//创建并使用 singleTon
//当我第一次调用 singleTon 的时候, instance 是 null
//就要执行 new Person 给 instance 赋值, 从此以后, instance 就是一个 Person 的实例了
//返回 instance    
const p1 = singleTon()
//当我第二次调用 singleTon 的时候         
//此时 instance 是第一次 new 出来的实例    
//if 条件就不会执行了, 直接返回第一次实例的地址     
const p2 = singleTon()    
console.log(p1, p2)    
console.log(p1 === p2)

观察者模式

    举例: 监控

          我们坐在教室里就是 被观察者

          监控后面的老师, 就是 观察者

      当被观察者触发了一些条件的时候, 观察者就会触发技能

      观察者模式: 监控一个 对象 的状态, 一旦状态发生变化, 马上触发技能

          需要两个构造函数来实现

          1. 创建被观察者

          属性, 自己的状态

          队列, 记录都有谁观察着自己, 数组[]

    方法, 能设置自己的状态, 当我需要改变的时候, 要触发这个方法改变状态

            能够添加和删除观察者

         2. 创建观察者

            需要一个身份证明和一个技能

// 观察者构造函数  
class Observer {    
constructor (name, fn = () => {}) {  
this.name = name        this.fn = fn     
}   
}
// 创建两个观察者  
const njzr = new Observer('年级主任', (state) => { 
console.log('因为: ' + state + ' , 你是哪个年级的') 
})   
const bzr = new Observer('班主任', (state) => {
console.log('因为: ' + state + ' , 明天叫你家长来学校')
})   
const xz = new Observer('校长', (state) => {
console.log('因为: ' + state + ' , 训斥你的班主任') })
// 被观察者的构造函数   
class Subject {      constructor (state) {
// 记录自己的状态        
this.state = state
// 数组用来保存观察着我的人       
this.observsers = []     
}
// 设置自己的状态      
setState (val) {    
this.state = val
// 把 我的所有观察者 的技能都触发        
this.observsers.forEach(item => {
// item 就是每一个观察者, 就是一个一个的对象
// 把每一个观察者的技能触发掉// 告诉他我改变成了什么状态          item.fn(this.state)      
})      
}
// 添加观察着     
addObserver (obs) {
// 谁是观察着, 是就传递谁进来
// 判断一下, 如果观察者已经存在, 就不再添加了       
this.observsers = this.observsers.filter(item => item !== obs)        this.observsers.push(obs)    
}
// 删除观察者     
delObserver (obs) {
// 把 obs 观察者删除,直接使用 filter 方法     
this.observsers = this.observsers.filter(item => item !== obs)  
}    }
// 创造一个被观察者   
const xiaoli = new Subject('学习')
   xiaoli.addObserver(njzr)    
   xiaoli.addObserver(bzr)   
   xiaoli.addObserver(xz)
    const xiaowen = new Subject('读书')   
    xiaowen.addObserver(bzr)  
    xiaowen.addObserver(xz)    
    console.log(xiaoli)   
    console.log(xiaowen)

       

   发布订阅模式

有对象, 就会有人一直看着他

        当这个对象发生变化的时候, 第三方通知这个看着的人, 触发技能

        举例: 买书

          1. 普通程序员买书

            去书店, 问, 没有, 回家

          过一会再去, 问, 没有, 回家

       2. 发布订阅的程序员

          去书店, 问, 没有, 留下一个联系方式给店员

            一旦有了书, 就会接到电话

            触发技能去买书

      只需要一个构造函数

        创建一个第三方店员的身份

          我们的任务就是模拟一个 addEventListener()

// 创建一个第三方观察着构造函数  
class Observer {     
constructor () {       
this.message = {}     
}
// 创建一个第三方观察着构造函数   
class Observer {     
constructor () { 
this.message = {}   
}
// 直接进行 push       
this.message[type].push(fn)     
}
// 2. 删除消息队列里面的内容     
off (type, fn) {
// 判断 如果 fn 不存在, 只有一个参数的情况      
if (!fn) {
// 直接把这个事情取消掉         
delete this.message[type]          
return        }
// 3. 触发消息队列     
trigger (type) {
// 判断是不是有订阅过        
if (!this.message[type]) return
// 找到这个数组, 把里面的每一个函数触发       
this.message[type].forEach(item => {
// item 就是每一个函数        
item() })     
}  
}
// 使用构造函数创建一个实例  
const person1 = new Observer()
// 当你向拜托这个 person1 帮你观察一些内容的时候
// 告诉你一个行为, 当行为出现的时候, 告诉你干什么   
person1.on('a', handlerA)   
person1.on('b', handlerB)
// 告诉 person1, 我这个事情不用你关了
// 1. 我只告诉你这个事情不用你管
// person1.off('a') 
// 把 消息队列 里面属于 a 的数组清空掉
// person1.off('a', handlerA) 
// 告诉你 a 发生的时候, 不用做 handerA 这个事情了  
person1.trigger('a')
// person1 这个人一旦触发 a 行为, 就要把后面的所有事件处理函数执行掉     console.log(person1)  
function handlerA() { 
console.log('handlerA') 
}    
function handlerB() { 
console.log('handlerB')
}    

   策略模式

        一个问题匹配多个解决方案, 不一定要用到哪一个

        而且有可能随时还会继续增加多个方案

        举例: 购物车结算

        当我们有好多种折扣计算方式

          满 100 减 10

          满 200 减 25

            普通会员 8 折

          高级会员 7 折

  1. 把我们的多种方案, 以闭包的形式保存起来

        按照传递进来的折扣和价格计算最终价格返回

      2. 留下添加折扣和删除折扣的接口

      函数也是一个对象

      可以把函数名当作一个对象, 向里面添加一些成员

 // 2.留下添加折扣和删除折扣的接口 
 const calcPrice = (function () { 
 const sale = {  
 '100_10': function (price) {return price -= 10},  
 '200_25': function (price) {return price -= 25},        
 '80%': function (price) { return price *= 0.8 }    
 } 
 function calcPrice(price, type) {    
 if (!sale[type])
 return '没有这个折扣'      
 return sale[type](price)   
 }
 // 把函数当作一个对象, 象里面添加一些成员    
 calcPrice.add = function (type, fn) {
 // 专门用来添加折扣
 // 判断这个折扣是不是存在       
 if (sale[type]) return '该折扣已经存在'
 // 代码来到这里, 表示折扣不存在       
 sale[type] = fn       
 return '添加成功'      
 }// 删除一个折扣      
 calcPrice.del = function (type) { 
 // 把对应的折扣删除掉       
 delete sale[type]      }    
 return calcPrice    })()
 // 使用的时候// 添加一个折扣   
 calcPrice.add('70%', function (price) { 
 return price *= 0.7 })   
 const res = calcPrice(320, '70%')   
 console.dir(res)    
 calcPrice.del('100_10')   
 const res2 = calcPrice(320, '100_10')  
 console.log(res2)

最后这里特殊说明一下

      观察者 和 发布订阅 两个设计模式

    市场上, 有一部分人认为是 一个, 一部分人认为是 两个

    我个人认为是两个。