Proxy

Proxy对象用于创建一个对象的代理,从而实现基本操作(如属性查找、赋值、枚举、函数调用等)的拦截和自定义

总共有13种拦截器,MDN - Proxy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let person = {nane:"yjsp",age:24}

// 参数1:被代理的引用类型 参数2:包含拦截器的配置项
let personProxy = new Proxy(person,{
// 拦截取值操作
// receiver:保证上下文的正确
get(target,key,receiver) {
if(target.age<=18) {
return target[key]
} else {
return "成年"
}
}
})

console.log(personProxy.age) // ->"成年"

Reflect

Reflect的所有属性和方法都是静态的,用于对对象进行语义化操作

总共有13种反射,MDN - Reflect

1
2
3
4
5
6
let person = {nane:"yjsp",age:24}

// 最后一个参数用于保持上下文的正确
console.log(Reflect.get(person,"name",person)) // ->"yjsp"
console.log(Reflect.set(person,"name","yajue",person)) // ->true(修改成功)
console.log(Reflect.get(person,"name",person)) // ->"yajue"

Proxy结合Reflect

反射可以操作对象,而且它的参数和拦截器一模一样,所以它们经常被一同使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 事件存储器
const list:Set<Function> = new Set()

// 订阅函数
const autorun = (cb:Function)=> {
if(!list.has(cb)) {
list.add(cb)
}
}

const observable = <T extends object>(params:T)=> {
return new Proxy(params,{
// 值改变时,依次调用回调函数
set(target,key,value,receiver) {
const result = Reflect.set(target,key,value,receiver)
list.forEach(fn=>fn())
return result
}
})
}

const personProxy = observable({name:"yjsp",age:24})

// 存储一个订阅函数
autorun(()=> {
console.log("发生了值的改变")
})

personProxy.name = "yajue"