首页手写ES6 Proxy

手写ES6 Proxy

Proxy本质是创建了一个代理。

我们再看第一节的代码:

//1: 定义一个target,名称随意,如 person
const person = {
  name: 'Jack'
};
//2:创建一个handler,名称随意,这里就叫handler
const handler = {
  //trap,提供属性访问的方法
  get(target, property) {
    console.log(`正在读取属性: ${property}`);
    return "Jack Ma"
  }
};
//3: 通过构造函数创建一个Proxy实例proxyPerson
const proxyPerson = new Proxy(person, handler);
console.log(proxyPerson.name); //Jack Ma
console.log(person.name);  //Jack, 针对target对象本身操作,没有任何效果

//------------------------------结果如下:
正在读取属性: name
Jack Ma
Jack

从上述的例子可以看出,被代理对象person的get和set不会经过代理拦截器get,set。

而只有代理对象proxyPerson在get和set方法调用的时候才会经过拦截器,由此可见ES6的代理Proxy并不是一个类似JAVA的AOP,而其实只是将person的引用赋值给了proxyPerson,让代理对象proxyPerson和被代理对象person指向了同一个内存空间

如果要自己实现Proxy,主要涉及到两点,一是深拷贝,而是使用ES5的Object.defineProperty。

以下仅供参考:

/*代理实现类*/
function MyProxy(target,handle){
  //deepClone略
  var targetCopy = deepClone(target);
  Object.keys(targetCopy).forEach(function(key){
    Object.defineProperty(targetCopy, key, {
      get: function() {
        return handle.get && handle.get(target,key);
      },
      set: function(newVal) {
        handle.set && handle.set();
        target[key] = newVal;
      }
    });
  })
  return targetCopy;
}

详细的可以参考:GitHub - GoogleChrome/proxy-polyfill: Proxy object polyfill