ES6的Proxy和Reflect

一:Proxy

Proxy 用于修改某些操做的默认行为,等同于在语言层面作出修改,因此属于一种“元编程”(meta programming),即对编程语言进行编程。编程

Proxy 能够理解成,在目标对象以前架设一层“拦截”,外界对该对象的访问,都必须先经过这层拦截,所以提供了一种机制,能够对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操做,能够译为“代理器”。bash

var obj = new Proxy({}, {
  get: function (target, key, receiver) {
    console.log(`getting ${key}!`);
    return Reflect.get(target, key, receiver);
  },
  set: function (target, key, value, receiver) {
    console.log(`setting ${key}!`);
    return Reflect.set(target, key, value, receiver);
  }
});
复制代码

上面代码对一个空对象架设了一层拦截,重定义了属性的读取(get)和设置(set)行为。这里暂时先不解释具体的语法,只看运行结果。对设置了拦截行为的对象obj,去读写它的属性,就会获得下面的结果。
编程语言

obj.count = 1
//  setting count!
++obj.count
//  getting count!
//  setting count!
//  2复制代码

ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。函数

var proxy = new Proxy(target, handler);复制代码

Proxy 对象的全部用法,都是上面这种形式,不一样的只是handler参数的写法。其中,new Proxy()表示生成一个Proxy实例,target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为。
ui

var proxy = new Proxy({}, {
  get: function(target, property) {
    return 35;
  }
});

proxy.time // 35
proxy.name // 35
proxy.title // 35复制代码

二:Reflect

一、将Object对象的一些明显属于语言内部的方法(好比Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在ObjectReflect对象上部署,将来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上能够拿到语言内部的方法。spa

二、修改某些Object方法的返回结果,让其变得更合理。好比,Object.defineProperty(obj, name, desc)在没法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false代理

三、让Object操做都变成函数行为。某些Object操做是命令式,好比name in objdelete obj[name],而Reflect.has(obj, name)Reflect.deleteProperty(obj, name)让它们变成了函数行为。code

四、Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象能够方便地调用对应的Reflect方法,完成默认行为,做为修改行为的基础。也就是说,无论Proxy怎么修改默认行为,你总能够在Reflect上获取默认行为。对象

Proxy(target, {
  set: function(target, name, value, receiver) {
    var success = Reflect.set(target,name, value, receiver);
    if (success) {
      log('property ' + name + ' on ' + target + ' set to ' + value);
    }
    return success;
  }
});

复制代码

上面代码中,Proxy方法拦截target对象的属性赋值行为。它采用Reflect.set方法将值赋值给对象的属性,确保完成原有的行为,而后再部署额外的功能。
部署

相关文章
相关标签/搜索