Proxy ~

概念

  • 为其他对象提供一种代理以控制对这个对象的访问
  • 直接访问会给使用者或者系统结构带来很多麻烦,在访问此对象时加上一层访问层
  • 装饰器模式不能改变原始对象的行为
  • 代理模式可以改变原始对象的行为(代理和目标都可自行扩展)

在这里插入图片描述

  • DOM 事件代理( 也叫事件委托 )
const container= document.getElementById('container')
container.addEventListener('click', function (e) {
  const target = e.target
  if (target.nodeName === 'A') {
    // ... do something
  }
})
  • 正向代理:webpack-dev-server ~ proxy
  • nginx 反向代理,客户端只需要根据服务端给定端口进行访问

理解

你通过房产中介买房子,中介就是一个代理

// 户主
class master {
  sign() {
    console.log('户主签字')
  }
}
// 代理
class agent {
  constructor() {
    this.master = new master()
  }
  // 签约
  sign() {
    // ... 按指纹、交定金、顾客签字等限制
    this.master.sign() // 和户主签约
  }
}
const proxy = new agent()
proxy.sign()

Proxy、Reflect

  • Proxy 用来创建一个对象的代理,可以实现数据的拦截和自定义
  • Reflect 不是一个构造器,不能通过 new 操作符实例,用于代理对象操作
  • get:读取、set:设置、deleteProperty:删除、ownKeys:遍历
let user = {}
user = new Proxy(user, {
  get(target, key) {},
  set(target, key, val) {},
  deleteProperty(target, key) {},
  ownKeys(target) {}
})

明星和经纪人,主办方需要联系经纪人进行签约和报价,而非联系明星。

// 明星
const star = {
  name: '张国荣',
  age: '18',
  address: '****', // 地址
  salary: '****', // 薪水
  phone: '****', // 号码
  price: 0 // 出场费
}

const min = 1000 * 1000 // 最少出场费
const agentTel = '139 **** 8888' // 经纪人电话
const privaInfo = ['salary', 'address'] // 私密信息不公开

// 经纪人
const agent = new Proxy(star, {
  get(target, key) {
    if (key === 'phone') {
      // 经纪人电话
      return agentTel
    } else if (privaInfo.includes(key)) {
      // 私密信息
      return undefined
    } else {
      return Reflect.get(target, key)
    }
  },
  set(target, key, val) {
    if (key === 'price' && typeof val === 'number') {
      // 出场费由积极人决定
      const newVal = val > min ? val : min
      return Reflect.set(target, key, newVal)
    }
    return false
  }
})

console.log(agent.phone) // '139 **** 8888' 经纪人电话
console.log(agent.price) // 100000 // 经纪人报价
console.log(agent.age) // 18 公开属性
console.log(agent.address) // undefined
console.log(agent.salary) // undefined
agent.price = 1000 * 1000 * 5
console.log(agent.price) // 5000000 // 经纪人修改后的报价

记录实例

const userList = new WeakSet() // 记录表 ~ 每次初始化 user 进行记录
class User {
  constructor(name) {
    this.name = name
  }
}
const ProxyUser = new Proxy(User, {
  construct(...args) {
    const user = Reflect.construct(...args)
    userList.add(user) // 记录
    return user
  }
})
const user1 = new ProxyUser('张三')

Notice

  • 捕获器不变式: 代理无法改变对象本身原有的属性设置
const obj = { y: 0 }
Object.defineProperty(obj, 'y', {
    value: 200,
    writable: false, // 不可更改
    configurable: false, // 不可配置
})
const proxy = new Proxy(obj, {
    get() {
        return 'abc'
    }
})
console.log(proxy.y) // y 属性描述符被修改,proxy 不能修改它的值
  • this: 函数里的 this 是由执行时确认的,而非定义时
const user = {
  name: '张三',
  getName() {
    console.log('this...', this)
    return this.name
  }
}
const proxyUser = new Proxy(user, {})
user.getName() // this 是 user
proxyUser.getName() //this 是 proxy
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值