1. 数据劫持升级
let obj = {
name:'张三',
age:18
}
let newObj = {}
Object.defineProperties(newObj,{
name:{
get(){ // 有人获取obj.name会触发
return obj.name
},
set(val){ // 有人修改obj.name会触发
obj.name = val
}
},
age:{
get(){
return obj.age
},
set(val){
obj.age = val
}
}
})
2. 数据劫持升级(自己劫持自己)
let obj = {
name:'张三',
age:18
}
for(let key in obj){
Object.defineProperties(obj,{
['_' + key] : {
value: obj[key],
writable:true
},
[key]:{
get(){
return obj['_' + key]
},
set(val){
obj['_' + key] = val
}
}
})
}
3. 数据代理(数据劫持)
-
ES6新增的内置构造函数
-
代码:const newObj = proxy(obj,{get(target,key){return target[key]},set(target,key,val){target[key] = val}})
let obj = {
name:'张三',
age:18
}
const newObj = new proxy(obj,{ // 这个obj位置是要劫持的对象
get(target,key){
return target[key]
},
set(target,key,val){
target[key] = val
return true // 如果修改简单数据类型需要加一个这个
}
})
obj.num = 100 // 此时会触发set(),这就是数据代理与数据劫持的差别
//target:当前代理的对象
//key:这个跟调用的值有关系
console.log(newObj.name) // 此时函数代理get()中第二个参数是name
4. 回调函数
-
条件: * 将函数A以实参的形式传递给函数B * 在函数B内以形参的形式调用函数A * 此时函数A就是函数B的回调函数
-
回调地狱 * 极其不利于阅读与维护,但是功能没有任何影响 * 封装异步代码很麻烦 ```js function fn(chenggong, shibai) { const num = Math.random() * 3000 + 3001 // 书写一个随机数, 用于倒计时器的等待时间
setTimeout(() => { // 根据 num 的值决定当前是成功还是失败 if (num > 3000) { console.log('网络请求超时, 购买失败', num) shibai() } else { console.log('购买成功', num) chenggong() } }, num)} fn(() => { console.log('执行成功后, 打印这个内容') }, () => { fn( () => { console.log('第二次买水成功, 打印这个内容') }, () => { console.log('第二次买水失败, 打印这个内容') fn( () => { console.log('第三次买水成功') }, () => { console.log('第三次买水失败') } ) } ) }) ```
5. promise
- 作用:解决回调地狱(是一种异步代码的封装方法)
promise其实就是一个盒子,内部放了一些异步代码
-
promise的三种状态 * 持续(正在运行):pending * 运行成功:fulfilled * 运行失败:rejected * 注意:promise只会从持续转为成功,或者从持续转为失败 ```js let p = new Promise(function (chenggong, shibai) { const num = Math.random() * 3000 + 1500 // 书写一个随机数, 用于倒计时器的等待时间
setTimeout(() => { // 根据 num 的值决定当前是成功还是失败 if (num > 3000) { console.log('网络请求超时, 购买失败', num) shibai() } else { console.log('购买成功', num) chenggong() } }, num) })// promise支持链式调用 p.then(function(){ // then 指向第一个形参返回的事 console.log('成功') }).catch(function(){ // catch 指向第二个形参返回的事 console.log('失败') }) ```
-
封装promise
js fn().then(()=>{ console.log('') return fn() }).then(()=>{ console.log('') }).catch(()=>{})```js function fn(){ return new Promise( (chenggong, shibai)=> { const num = Math.random() * 3000 + 1500 // 书写一个随机数, 用于倒计时器的等待时间setTimeout(() => { // 根据 num 的值决定当前是成功还是失败 if (num > 3000) { console.log('网络请求超时, 购买失败', num) shibai() } else { console.log('购买成功', num) chenggong() } }, num) })} fn().then(()=>{ console.log('第一次成功') return fn() }).then(()=>{ console.log('第二次成功') return fn() }).then(()=>{ console.log('第三次成功') return fn() }).then(()=>{ console.log('第四次成功') return fn() }).then(()=>{ console.log('第五次成功') return fn() }).catch(()=>{ console.log('上述某一次失败了,我都可以捕获到') }) ```
6. async 和 await
-
作用:将异步代码书写的跟同步代码一样
-
需求: * 需要结合一个函数 * 需要结合一个promise对象
-
弊端:不能捕获到promise的错误状态,一旦promise返回的是错误信息,那么会报错阻断程序的运行 * async和await不能捕获到promise的错误状态,但是可以捕获到promise的成功状态
-
解决方法: * 封装的 promise 不在返回 失败状态, 永远返回一个成功状态,所以为了区分这次的状态到底是成功了还是失败了, 需要在返回的信息上做一些修改 * 返回的信息是目前开发中比较常用的一个标准,返回一个对象, 内部的 code 属性代表当前是成功还是失败, 成功值为1, 失败值为0,第二个属性的属性名, 不确定, 但是代表的是这个请求的一些信息
-
解决方法 * try...catch * 改变 promise 的封装, 不在返回一个失败状态, 永远返回成功状态 ```js function myPro() { const p = new Promise(function (res, rej) { // 书写 异步代码 const num = Math.random() * 3000 + 2000 setTimeout(() => { if (num > 3000) { // console.log('网络请求超时, 购买失败', num) // rej('当前请求超时, 可能是用户电脑网线问题') res({ code: 0, info: '当前请求超时, 可能是用户电脑网线问题' }) } else { // obj 为 模拟的一个数据 const obj = { id: 1, name: '电视机', info: { width: 2, height: 1 } } // console.log('购买成功', num) res({ code: 1, info: obj }) } }, num) })
return p}
async function fn() { const res = await myPro() if (res.code === 0) { // 处理一些 请求失败要做的事 console.log(res.info) } else { // 处理一些请求成功要做的事 console.log(res.info) }
const res1 = await myPro() console.log(res1.code)}
fn() ```
7. promise的一些方法
-
finally(function(){}) * 定义:请求完毕后执行的一些事情
-
Promise构造函数上的一些方法 * promise.all([需要书写一些promise实例化对象])
js Promise.all([]).then(function(){}).catch(function(){}) // 都成功的时候会执行或者有一个失败的时候会执行* Promise.race([需要书写一些promise实例化对象])js Promise.race([]).then(function(){}).catch(function(){}) // 传递的Promise对象中第一个结束的状态为成功时执行,第一个结束的状态为失败时执行* Promise.allSettled([需要书写一些promise实例化对象])js Promise.allSettled([]).then(function(){}).catch(function(){}) // 会把Promise所有运行的结果都打印出来,打印成数组形式* Promise.resolve([需要书写一些promise实例化对象])js promise.resolve([]).then(function(){}).catch(function(){}) // 一定会返回一个为成功状态的对象,catch一定不会执行* Promise.reject([需要书写一些promise实例化对象])js promise.reject([]).then(function(){}).catch(function(){}) // 一定会返回一个为失败状态的对象,then一定不会执行