proxy

发布时间 2023-07-27 17:56:16作者: 加利福尼亚的阳光

ES6新增Proxy对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。

语法

/* 
  参数1: 用Proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
  参数2: 一个对象,其属性是当执行一个操作时定义代理的行为的函数。(操作时的具体)
*/
const proxy = new Proxy(targe, handler)

栗子

const obj = {
  firstName: 'JOJO',
  age: 18,
  children: {
    obj2: {
      firstName: '鸡哥'
    },
    obj3: {
      firstName: '坤坤'
    }
  },
  hobby: ['吃饭', '睡觉'],
}

const handler = {
  // 参数3: Proxy 或者继承 Proxy 的对象 
  get(obj, key, receiver) {
    return key in obj ? obj[key] : '没有'
  },
  set(obj, key val) {
    obj[key] = val
  },

  /* 
    除了 get set proxy 还提供多种拦截操作
  */
  /* 
    handler.has() 方法是针对 in 操作符的代理方法。
    console.log('firstName' in proxy) false
  */
  has(obj, key) {
    if(key === 'firstName') {
      return false
    }
  },
  /* 
    handler.ownKeys() 方法用于拦截 Reflect.ownKeys()
    Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组
    for (const key in proxy) {
      console.log(key); // age
    }
  */
  ownKeys(obj) {
    return Reflect.ownKeys(obj).filter(key => key === 'age');
  }
}

深度侦听

function ob (obj) {
  const handler = {
    get (obj, key, receiver) {
      if (typeof obj[key] === 'object') return new Proxy(obj[key], handler);
      console.log('get', key, obj[key]);
      return key in obj ? obj[key] : 'undefined';
    },
    set (obj, key, value) {
      if (typeof value === 'object') return new Proxy(value, handler);
      console.log('set', key, value);
      obj[key] = value;
    }
  };
  return new Proxy(obj, handler);
}