day34
一、设计模式
+ 设计模式是一些对解决问题的总结和经验,设计模式是解决某个问题的最佳的方案,无数人优秀人的程序员的实验和错误总结 + 共23种
1.工厂模式
=> 对于批量创建对象的一种解决方案 => 函数可以传递参数 => 本质利于函数的特性,然后在函数内部创建一个对象,每次传递参数,把新的对象以返回值的形式返回
function person(name, age){ let obj = { name, age } obj.say = function(){ console.log(this.name + '喜欢演讲!') } return obj } let p1 = person('张', 18) let p2 = person('陈', 18) console.log(p1, p2) function Person(name, age){ this.name = name this.age = age this.say = function(){ console.log(this.name + '喜欢演讲!') } }
2.单例模式(一个类一生中只能有一个实例化对象)
class Person { constructor(){} init(name){ this.name = name } // static可以把原型方法变成静态方法 static getInstance(name){ if(!this.instance){ this.instance = new Person(name) } this.instance.init(name) return this.instance } } let p1 = Person.getInstance('张') // let p2 = Person.getInstance('陈') console.log(p1)
function Person(name){ } Person.prototype.init = function(name){ this.name = name } // 单例模式核心代码,使用静态方法 Person.getInstance = function(name){ // instance是绑定给Person构造函数的一个属性,这里取反,说明可以进入判断体里面,因为第一次的时候this.instance没有值的,所以是undefined if(!this.instance){ this.instance = new Person(name) } // 每次返回之前,先调用一次init方法,把参数传递进来 this.instance.init(name) // 如果是第二次进来,那么说明有这个实例化对象了,那么直接把实例化对象返回 return this.instance } let p1 = Person.getInstance('张') let p2 = Person.getInstance('陈') console.log(p1, p2) // true
单例模式弹窗
样式:
*{ margin: 0; padding: 0; } html, body{ height: 100%; } button{ width: 100px; height: 28px; margin: 10px; } .mask{ width: 100%; height: 100%; background-color: rgba(0, 0, 0, .5); position: fixed; top: 0; left: 0; display: none; } .mask .content{ width: 500px; height: 300px; background-color: #fff; position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto; display: block; } .mask .content span{ position: absolute; right: 0; top: 0; width: 15px; height: 15px; background-color: #ccc; color: #fff; text-align: center; line-height: 15px; font-size: 12px; cursor: pointer; } .mask .content p{ text-align: center; line-height: 300px; } /* 自定义三个背景颜色 */ .sy1{ background-color: hotpink !important; } .sy2{ background-color: orange !important; } .sy3{ background-color: greenyellow !important; } <button>弹窗1</button> <button>弹窗2</button> <button>弹窗3</button> <div class="mask"> <div class="content"> <span>×</span> <p></p> </div> </div>
let aBtn = document.querySelectorAll('button') class Layer { constructor(){} init(text, sy){ this.mask = document.querySelector('.mask') this.content = document.querySelector('.content') this.p = document.querySelector('p') this.span = document.querySelector('span') this.content.classList.add(sy) this.p.innerHTML = text this.show() this.hide(sy) } show(){ this.mask.style.display = 'block' } hide(sy){ this.span.onclick = ()=>{ this.mask.style.display = 'none' this.content.classList.remove(sy) } } static getInstance(text, sy){ if(!this.instance){ this.instance = new Layer(text, sy) } this.instance.init(text, sy) return new Layer(text, sy) } } aBtn[0].onclick = ()=>{ Layer.getInstance('张特别喜欢这个弹窗', 'sy1') } aBtn[1].onclick = ()=>{ Layer.getInstance('陈说嘿嘿', 'sy2') } aBtn[2].onclick = ()=>{ Layer.getInstance('王喜欢美女', 'sy3') }
3.发布订阅模式(一种对象间一对多的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都将得到状态改变的通知)
// 例如:报名千锋的课程 // Lsson就是一个调度中心,所谓的调度中心其实就是平台 class Lesson { constructor(){ // 数据结构设计,对象加数组格式 this.message = {} console.log(this.message) } add(type, fn){ // 判断下对象里面是否存在某个类型的课程 // this.message['HarmonyOS']第一次进来没有这个课程,值是undefined,取反就进入判断体里面 if(!this.message[type]){ // 可以把这个属性添加进对象,并赋值为数组 this.message[type] = [] } this.message[type].push(fn) } cancel(type, fn){ // 判断下有没有这个课程,如果没有就终止函数执行 if(!this.message[type]) return // 可以使用过滤 // zt != zt false // wwn != zt true this.message[type] = this.message[type].filter(item=> item != fn) } emit(type, info){ // 判断下有没有这个课程,如果没有就终止函数执行 if(!this.message[type]) return // 如果有这个课程就通知 this.message[type].forEach(item=>{ item(info) }) } } let qf = new Lesson() function zt(info){ console.log('张报名了HarmonyOS课程,' + info) } function wwn(info){ console.log('王报名了HarmonyOS课程,' + info) } function ty(info){ console.log('陶报名了HarmonyOS课程,' + info) } function cjh(info){ console.log('陈报名了JavaEE课程,'+ info) } function lsj(info){ console.log('李报名了JavaEE课程,'+ info) } // 参数1表示的是课程名称,课程类型 qf.add('HarmonyOS', zt) qf.add('HarmonyOS', wwn) qf.add('HarmonyOS', ty) qf.add('JavaEE', cjh) qf.add('JavaEE', lsj) // 可以报名课程,也可以取消课程 // 参数1表示取消课程的类型 // 参数2表示谁取消课程 // qf.cancel('HarmonyOS', zt) // 发布开课信息 // 参数1表示开课的类型 // 参数2表示课程相关的信息 qf.emit('JavaEE', '11月11号开课了,请到肖家河大厦三楼前台报道') let btn = document.querySelector('button')
4.策略模式(定义一系列的算法,将他们一个个封装起来,使他们直接可以相互替换。)
例:需要实现一个计算员工奖金的程序,效绩为 S 则发基本工资的4倍,A 则3倍,以此类推
// 策略模式 let obj = { "S": function(price){ return price * 4 }, "A": function(price){ return price * 3 }, "B": function(price){ return price * 2 } } function calc(leval, price){ return obj[leval](price) } // 通过函数的静态方法,新增一个等级 calc.add = function(leval){ obj[leval] = function(price){ return price * 1.5 } } calc.add('C') // 新增一个删除等级方法 calc.del = function(leval){ delete obj[leval] } calc.del('S') console.log(obj)
二、ajax(用于前后端数据交互)
+ 是用来和后端交互数据的一种技术,你可以通过ajax给后端传递数据,也可以接收后端传递过来的数据 + ajax不是一个新的技术,实际上是几个技术的组合 => xml 数据交互格式 --- json => http 协议 => request 请求 + 注意点 => 发送请求,必须在服务器的环境下 + 接收服务器返回的请求信息 => xhr.responseText => 接收返回的字符串和json数据 => xhr.responseXML => 接收返回的xml格式的数据 => xhr.response => 接收xml、字符串、json数据 xhr.readyState + 返回当前请求的状态 + 通过这个属性查看ajax请求进行到哪一个步骤了 => 0时-未初始化, 对象已建立, 尚未调用open() => 1时-初始化, 对象建立未调用send() => 2时-发送数据, send()方法调用, 但是当前的状态及http头未知, 请求未完成 => 3时-数据传输中,接受部分数据(如果数据量比较小的时候的,3的时候其实就可以接收完成,如果数据量比较大的时候,3表示只能接收部分数据接收不完整) => 4时-响应内容解析完成
// 实例化ajax对象 let xhr = new XMLHttpRequest() // console.log(xhr.readyState) // 0时-未初始化, 对象已建立, 尚未调用open() /* 配置信息 + 你要给那个服务器发送请求,告诉ajax,你的请求方式是什么,告诉ajax,你发送的请求是同步的还是异步的,告诉ajax + 参数1表示请求类型 + 参数2表示的是请求地址(api) + 参数3表示的是同步还是异步,默认就是异步的 基准地址 + http://localhost:8888 + 根地址 --- / */ // xhr.open('get', 'http://localhost:8888/test/first') xhr.open('get', 'http://localhost:8888/test/second') // console.log(xhr.readyState) // 1时-初始化, 对象建立未调用send() // 监听请求状态 xhr.onreadystatechange = ()=>{ // 2时-发送数据, send()方法调用, 但是当前的状态及http头未知, 请求未完成 // 3时-数据传输中, 接受部分数据 // 4时-响应内容解析完成 // console.log(xhr.readyState) // console.log(xhr.responseText) if(xhr.readyState === 4){ if(xhr.status === 200){ // console.log(xhr.responseText) console.log(JSON.parse(xhr.responseText)) }else{ console.log('请求失败') } } // if(xhr.readyState === 4 && xhr.status === 200){ // console.log(xhr.responseText) // }else{ // console.log('请求失败') // } } // 发送请求 xhr.send()
三、两个请求(get=>Query String Parameters post =>Form Datas)
1.get请求
let btn = document.querySelector('button') btn.onclick = ()=>{ // 创建ajax对象 let xhr = new XMLHttpRequest() // 填写配置信息 // get请求传递参数,使用查询字符串格式 // 注意点:get请求会存在缓存问题,一般会返回304http状态码。拼接时间戳的目的是让地址每次变化不一样,解决缓存问题 xhr.open('get', `http://localhost:8888/test/third?name=张&age=18&time=${Date.now()}`) // 监听请求状态 xhr.onreadystatechange = ()=>{ if(xhr.readyState === 4){ if(xhr.status === 200){ console.log(JSON.parse(xhr.responseText)) }else{ console.log('请求失败') } } } // 发送请求 xhr.send() }
2.post请求
let btn = document.querySelector('button') btn.onclick = ()=>{ // 创建ajax对象 let xhr = new XMLHttpRequest() // 填写配置信息 // get请求传递参数,使用查询字符串格式 xhr.open('post', 'http://localhost:8888/test/fourth') // 携带请求头信息,这个是post请求规定的,因为post安全性比较高的 // application/x-www-form-urlencoded表示以form表单的数据格式来给后端传递数据 xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded') // 监听请求状态 xhr.onreadystatechange = ()=>{ if(xhr.readyState === 4){ if(xhr.status === 200){ console.log(JSON.parse(xhr.responseText)) }else{ console.log('请求失败') } } } // 发送请求 // post传递参数不能使用查询字符串,必须在send()方法里面传递 xhr.send('name=张&age=18') }
3.get请求封装
+ 参数 => @parmas { string } url 表示要请求的地址(api接口地址) => @parmas { object } parmas 表示请求的参数 => @parmas { function } success 表示成功时的回调函数 => @parmas { function } error 表示失败时的回调函数
function ajax_get(url, parmas, success, error){ let xhr = new XMLHttpRequest() // 判断是否存在请求参数 if(parmas){ // 能进来说明存在参数 // 把对象转成查询字符串 let str = '?' for(let key in parmas){ // str +=name='张' str += `${key}=${parmas[key]}` str += '&' } str = str.slice(0, -1) xhr.open('get', url+str) }else{ // 这里说明没有参数 xhr.open('get', url) } xhr.onreadystatechange = ()=>{ if(xhr.readyState === 4){ if(xhr.status === 200){ success && success(xhr.responseText) }else{ error && error() } } } xhr.send() } ajax_get('http://localhost:8888/test/third', {name: '张', age: 18}, function(result){ console.log(JSON.parse(result)) }, function(){ console.log('请求失败') })
4.get请求封装优化
function ajax_get(options){ let xhr = new XMLHttpRequest() // 判断是否存在请求参数 if(options.params){ // 能进来说明存在参数 // 把对象转成查询字符串 let str = '?' for(let key in options.params){ // str +=name='张' str += `${key}=${options.params[key]}` str += '&' } str = str.slice(0, -1) xhr.open('get', options.url+str) }else{ // 这里说明没有参数 xhr.open('get', options.url) } xhr.onreadystatechange = ()=>{ if(xhr.readyState === 4){ if(xhr.status === 200){ options.success && options.success(xhr.responseText) }else{ options.error && options.error() } } } xhr.send() } // ajax_get('http://localhost:8888/test/third', {name: '张', age: 18}, function(result){ // console.log(JSON.parse(result)) // }, function(){ // console.log('请求失败') // }) ajax_get({ url: 'http://localhost:8888/test/third', params: {name: '张', age: 18}, success(result){ console.log(JSON.parse(result)) }, error(){ console.log('请求失败') } })
5.post请求封装
function ajax_post(options){ let xhr = new XMLHttpRequest() xhr.open('post', options.url) xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded') xhr.onreadystatechange = ()=>{ if(xhr.readyState === 4){ if(xhr.status === 200){ options.success && options.success(xhr.responseText) }else{ options.error && options.error() } } } if(options.params){ // 把对象转成查询字符串 let str = '' for(let key in options.params){ // str +=name='张' str += `${key}=${options.params[key]}` str += '&' } str = str.slice(0, -1) xhr.send(str) }else{ xhr.send() } } ajax_post({ url: 'http://localhost:8888/test/fourth', params: {name: '张', age: 18}, success(result){ console.log(JSON.parse(result)) }, error(){ console.log('请求失败') } })
6.函数参数对象化(使用的过程中需要注意参数的顺序问题,如果参数比较多的情况下,很容易混淆参数表示意义)
function fn(options){ options.arr.push('hello') console.log(options.num + 666) console.log(options) } fn({ num: 10, arr: [10, 20, 30], })标签:function,console,log,xhr,学习,HarmonyOS,let,关于,name From: https://blog.csdn.net/m0_72035166/article/details/142364572