ES6 Proxy/Reflect 浅析

ES6 Proxy/Reflect

Proxy 阻拦器

proxy是es6的新特征,简朴来说,等于对目的对象的属性读取、设置,亦或函数挪用等操纵举行阻拦(处置惩罚)。

let proxy = new Proxy(target,handle)

target

一个proxy代办对象由两部分构成target/handle。个中target为目的对象,可以为一个空对象即(target={}),也可所以一个含有属性和要领的对象(target={foo:1,bar:2}),在举行let proxy=new Proxy(target,handle)的操纵后,新的proxy对象会对target举行“浅拷贝”,即proxy、target两个对象会相互影响。即:

let target = { _prop: 'foo', prop: 'foo' };
let proxy = new Proxy(target, handler);
proxy._prop = 'bar';
target._attr = 'new'
console.log(target._prop) // 'bar'
console.log(proxy._attr) //'new'

ES5 getter/setter

handle是现实运转的处置惩罚要领,Proxy的handle一共有13种要领,以最简朴经常运用的get/set要领为例。在ES5中,对象就有get/set的接见器(低版本浏览器不支持),它们的作用是在对象举行属性的读写时,举行分外的操纵。比方person对象下的age属性,当它不在0-100之间时,给这个age的值重置为0。

var person = {
                get age(){
                    console.log('getter')
                    return this._age;//这里万万不能return this.age,会失足
                },
                set age(val) {
                    console.log('setter')
                    this._age = val < 100 && val > 0 ? val:0
                   
                }
            };
    person.age = 10 //10
    person.age = 101 //0
    person.age = 'age' //0

在举行赋值操纵时,会先触发set、后触发get,举行如person.age++的操纵时,set、get的触发递次为:get=>set。以上就是ES5的getter/setter接见器。

handle

在 Proxy中的handle中get、set要领也相似。即

   let handler = {
                get (target, key){
                    return target[key]
                },
                set (target, key, value) {
                    if (key === 'age') {
                        target[key] = value > 0 && value < 100 ? value : 0
                    }
                    return true;//必须有返回值
                }
            };

            let target = {};
            let proxy = new Proxy(target, handler);
            proxy.age = 22 //22

个中get可接收三个参数(target,key, receiver),target为目的对象,key为属性名,receiver为现实接收的对象,默以为本例中新建的proxy,假如零丁指出一个对象,可以使指出对象遭到雷同的要领作用。比方:

   let _proxy={};
   let handler = {
                get (target, key , receiver){
                    receiver=_proxy;
                    target[key]='test';
                    return Reflect.get(target,key,receiver);
                },
                set (target, key, value) {
                    if (key === 'age') {
                        target[key] = value > 0 && value < 100 ? value : 0
                    }
                    return true;//必须有返回值
                }
            };

            let target = {};
            let proxy = new Proxy(target, handler);
            proxy.age
            console.log(_proxy.age) // test

set要领 多一个value参数,为属性值,即 proxy.age=1,中的1。

与ES5 setter/getter接见器的区分是,在proxy中,proxy.age=1,只会实行 set的要领,而不是像ES5中的setter,会先实行set,后实行get。且proxy中的set必须有返回值,ES5的setter不必,这也恰是由于在他以后还会实行getter,所以不需要。

Reflect 反射

Reflect与ES5的Object有点相似,包含了对象言语内部的要领,Reflect也有13种要领,与proxy中的要领一一对应。Proxy相当于去修正设置对象的属性行动,而Reflect则是猎取对象的这些行动。
照样适才的例子:

 let _proxy = {}
 let handler = {
                get (target, key,recive){
                    return Reflect.get(target,key,recive)
                },
                set (target, key, value) {
                    if (key === 'age') {
                        target[key] = value > 0 && value < 100 ? value : 0
                    }
                    return Reflect.set(target,key,value,_proxy);
                }
            };

  let target = {};
  let proxy = new Proxy(target, handler);
  proxy.age = 33
  console.log(_proxy.age)//33

Reflect 也可与ES5的setter/getter合营运用,比方:

var myObject = {
  foo: 1,
  bar: 2,
  get baz() {
    return this.foo + this.bar;
  },};

var myReceiverObject = {
  foo: 4,
  bar: 4,};

Reflect.get(myObject, 'baz', myReceiverObject) // 8

其他要领与Proxy均雷同,区分等于,设置和猎取的关联。

Proxy和Reflect另有许多要领,比方apply作为操纵对象函数时触发的要领,比方myObject =function(){
return “it’s Fn”}, myObject();会触发handle中的apply要领。另有触发has要领的_attr in obj等等总计13种要领,本次只以最简朴的set、get要领来举例。

    原文作者:j_bleach
    原文地址: https://segmentfault.com/a/1190000008326517
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞