TODO:Proxy&Reflect

代理 Proxy

创建一个对象的代理对象,从而实现基本操作的拦截和自定义

  • 代理对象创建:new Proxy(target, handler)
  • 创建一个可撤销的代理对象:Proxy.revocable(target, handler);

ES5 对象通过get set方法实现属性代理

let p1 = { _name: 'abc' }
Object.defineProperty(p1, 'name', {
  get() {
    console.log('get')
    // doSomething()
    return this._name
  },
  set(val) {
    console.log('set')
    // doSomething()
    this._name = val
  }
})

使用 ES6 Proxy 实现属性操作代理和拦截

let student = {
  name: 'lee',
  range:[2, 5],
  _pwd: 'xxxx',
  [Symbol('skill')]: '演讲'
}

console.log(Object.keys(student)) // ["name", "range", "_pwd"]

student = new Proxy(student, {
  get(target, propKey) {
    return propKey in target ? target[propKey] : 'no value'
  },
  set(target, propKey, value) {
    console.log(`set ${propKey} to bo ${value}`)
    target[propKey] = value
  },
  deleteProperty(target, propKey) {
    if(propKey === 'name') {
      throw new Error('name 属性不可删除')
    }else {
      delete target[propKey]
    }
  },
  has(target, propKey) {
    const [start, end] = target.range
    return propKey > start && propKey < end
  },
  // 下划线开头属性为私有属性,不能遍历
  ownKeys(target) {
    return Object.keys(target).filter((item) => {
      return !item.startsWith('_')
    })
  }
})
console.log(3 in student) // true
console.log(6 in student) // false
console.log(student.age) // no value
student.age = 12 // set age to bo 12
console.log(student.name) // 12
console.log(Object.keys(student)) // ["name", "range", "age"]
try{
  delete student.name
}catch(e){
  console.log(e.message) // name 属性不可删除
}

反射 Reflect

ES6 提供的操作对象 API,若需要再 Proxy 内部调用对象的默认行为,建议使用Reflect

  • 只要Proxy对象具有的代理方法,Reflect对象全部都要,以静态方法的形式存在
  • 定义不存在属性行为的时候不报错,而是返回false

Proxy 是代理,Reflect 是干嘛用的?

results matching ""

    No results matching ""