Proxy、Reflect

// Proxy是es6新增的拦截器,总共拦截十三种,代理
// Reflect是反射,跟Proxy的方法一样是十三种,对应的参数一模一样

// Proxy是代理引用类型,对象、数组、map、set、函数

let person = {name:'bai',age:14}
const personProxy = new Proxy(person,{
  // target 是指传入的对象
  // key 是属性
  // value 是修改时传入的值
  // receiver 是怕多次使用箭头函数this指向乱而设定的,实际值是代理的引用对象,保证上下文正确
  get(target,key,receiver){
    // 这里使用Reflect是因为1.es6官方推荐使用Reflect来操作对象
    // 2.是Reflect和Proxy的方法和类型一模一样,直接传值参使用即可
    return Reflect.get(target,key,receiver)
  },
  set(target,key,value,receiver) {
    // Reflect.set返回的也是布尔值,所以非常方便
    return Reflect.set(target,key,value,receiver)
  },
  // 拦截函数调用
  apply() {

  },
  // 拦截in操作符
  has() {
    return true
  },
  // 拦截for in语法
  ownKeys() {
    return []
  },
  // 拦截new操作符
  construct() {
    return {}
  },
  // 拦截delete操作符
  deleteProperty(target, p) {
    return true
  }
})

// proxy版的观察者模式
// 定义事件存储Set
const callbackList:Set<Function> = new Set([])
// 事件存储逻辑
function autoSet(cb:Function) {
  if (!callbackList.has(cb)) {
    callbackList.add(cb)
  }
}
// 定义一个proxy,当他被读值的时候事件发布
const proxy = new Proxy({name: 'gaogaogao'},{
  get(target,key,receiver) {
    callbackList.forEach(element => {
      element()
    });
    return Reflect.get(target,key,receiver)
  }
})
// 订阅事件
autoSet(()=>{
  console.log('giao');
})
console.log(proxy.name); //giao gaogaogao

 

posted on 2025-02-18 13:47  ChoZ  阅读(28)  评论(0)    收藏  举报

导航