资讯专栏INFORMATION COLUMN

ES6 Proxy/Reflect 浅析

Juven / 1871人阅读

摘要:即必须有返回值其中可接受三个参数,为目标对象,为属性名,为实际接受的对象,默认为本例中新建的,如果多带带指出一个对象,可使指出对象受到相同的方法作用。且中的必须有返回值,的不用,这也正是因为在他之后还会执行所以不需要。

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方法来举例。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81483.html

相关文章

  • ES6学习笔记4-ProxyReflect、Decorator、Module

    摘要:拦截实例作为构造函数调用的操作,比如。方法等同于,这提供了一种不使用,来调用构造函数的方法。方法对应,返回一个布尔值,表示当前对象是否可扩展。这是的一个提案,目前转码器已经支持。别名或修饰器在控制台显示一条警告,表示该方法将废除。 Proxy Proxy 这个词的原意是代理,用在这里表示由它来代理某些操作,可以译为代理器,即用自己的定义覆盖了语言的原始定义。ES6 原生提供 Proxy...

    lushan 评论0 收藏0
  • 【资源集合】 ES6 元编程(Proxy & Reflect & Symbol)

    摘要:理解元编程和是属于元编程范畴的,能介入的对象底层操作进行的过程中,并加以影响。元编程中的元的概念可以理解为程序本身。中,便是两个可以用来进行元编程的特性。在之后,标准引入了,从而提供比较完善的元编程能力。 导读 几年前 ES6 刚出来的时候接触过 元编程(Metaprogramming)的概念,不过当时还没有深究。今天在应用和学习中不断接触到这概念,比如 mobx 5 中就用到了 Pr...

    aikin 评论0 收藏0
  • ES6Proxy & Reflection API

    摘要:的出现,使用内建对象的继承得以实现。属性不存在抛出异常是取值操作,而就是赋值操作,可以对属性值进行验证。属性必须为数字抛出异常接受两个参数被读取属性的原对象,即代理的目标。这个可以拦截内部方法,通过返回数组的值可以覆写其行为。 Proxy & Reflect extends的出现,使用内建对象的继承得以实现。Proxy可以拦截JS引擎内部目标的底层对象操作,这些底层操作被拦截后会触发响...

    yearsj 评论0 收藏0
  • 初入ES6-ProxyReflect

    摘要:用于修改某些操作的默认行为和访问器属性的行为类似在对象的前面多一层代理,对象字面量中定义属性的特性方法,访问器属性此时属性被定义为访问器属性不一样的写法中是用代理的写法第一个参数是对象,第二个是要操作的方法对象也有两个属性,一个是目标对象, 1,Proxy用于修改某些操作的默认行为和访问器属性的行为类似,在对象的前面多一层代理, const obj = { ...

    BakerJ 评论0 收藏0
  • 初识ProxyReflect

    摘要:主要原因应该是在处理数组响应是会存在缺陷。构造函数其中表示生成一个实例,为需要代理的对象,则是一个对象,定义了各种代理行为。对于满足条件的属性以及其他属性,直接保存报错报错拦截的操作,返回一个布尔值。 前言 https://segmentfault.com/a/11... Vue3.0应该马上就要发布正式版了。听说在新版本中,Proxy取代了Object.defineProperty进...

    gougoujiang 评论0 收藏0

发表评论

0条评论

Juven

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<