ES6 Reflect


1.reflect 概述


Reflect 对象与Proxy对象一样,也是ES6为了操作对象而提供的新的Api。Reflect对象的设计目的有以下几个。

  • 1.1将Object对象上的一些明显属于语言内部的方法(类如Object.defineProperty)放到Reflect对象上。现阶段某些方法同时在Object和Recflect对象上部署,未来的新方法将旨在Reflect对象上部署。也就是说在Reflect对象上可以获得语言内部的方法。

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

 旧写法
        try{
            Object.defineProperty(target, property, attributes);
            //success
        } catch(e){
            //faliure
        }

        新写法
        if(Reflect.defineProperty(target, property, attributes){
            //seccess
        }else{
            //failure
        }
  • 1.3让Object操作都编程函数行为。某些Object操作是命令时,比如 name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect。delete Property(obj, name)让他们变味了函数行为。
//旧写法
'assign' in Object  //true

//新写法
Reflect.has(Object, 'assign')  //true
  • 1.4Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能放在Reflect对象上找到相应的方法。这就是Proxy对象可以方便的调用相应的Reflect方法来完成默认行为,作为修改行为的基础。也就是说,无论proxy怎么修改默认行为,我们总可以在Reflect上获取默认行为。
		2.
        Proxy(target,{
            set(target, name, value, recevier){
                let success = Reflect.set(target, name, value, recevier);
                if(success){
                    console.log('property' + name + 'on' + target + 'set to' + value); 
                }
                return success;
            }
        })

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



        3.再举一个例子
        {
            let obj = {name:'康家豪'}
            let loggedObj = new Proxy(obj, {
                get(target, name) {
                    console.log('get', target, name);
                    return Reflect.get(target, name);
                },
                deleteProperty(target, name) {
                    console.log('delete' + name);
                    return Reflect.defineProperty(target, name);
                },
                has(target, name){
                    console.log('has' + name);
                    return Reflect.has(target, name);
                }
            });
        }

    上面的代码中,每一个Proxy对象的拦截操作,内部都调用了相应的Reflect方法,保证了原生行为能够正常执行。
    添加的工作就是将每一个操作输出一行日志。

2.Reflect的静态方法


  • Reflect.apply(target, thisArg, args);
  • Reflect.construct(target, args)
  • Reflect.get(target, name, receiver)
  • Reflect.set(target, name, value, receiver)
  • Reflect.defineProperty(target, name, desc)
  • Reflect.deleteProperty(target, name)
  • Reflect.has(target, name)
  • Reflect.ownKeys(target)
  • Reflect.isExtensible(target)
  • Reflect.preventExtensions(target)
  • Reflect.getOwnPropertyDescriptor(target, name)
  • Reflect.getPrototypeOf(target)
  • Reflect.setPrototypeOf(target, prototype)

上面的这些方法的作用大部分与Object对象的同名方法的作用是想扽给的,而且与Proxy对象的方法是一一对应的。


3.实例方法


  • 1.Reflect.get(target, name, receiver)
    Reflect.get()方法用于查找并返回target对象的property属性
  {
            let obj = {
                name: "kjh",
                age:18,
                get say(){
                    return this.name + this.age;
                }
            }
            let result1 = Reflect.get(obj, "name");
            let result2 = Reflect.get(obj, "age");
            let result3 = Reflect.get(obj, "say")
            console.log(result1) //kjh 
            console.log(result2) //18
            console.log(result3) //kjh18
        }


        // //如果部署了读取函数(getter),则读取函数的this绑定recevier。
        {
            let obj = {
                name:'kjh',
                age:18,
                get say(){
                    return this.name + this.age;
                }
            }

            let myRecevierObj = {
                name:'oiu',
                age:99
            }

            console.log(Reflect.get(obj, 'say', myRecevierObj));
            //oiu99
        }
  • 2.Reflect.set(target,property,value,receiver)
    Reflect.set用于设置对象target的property属性为value
 {
            let obj = {
                id:0,
                set bar(value){
                    return this.id = value;
                }
            };
            console.log(obj.id);  //0
            console.log(Reflect.set(obj,'id',9));  //true
            console.log(obj.id);   //9
        }


        {
            let obj = {
                id:0,
                set bar(value){
                    return this.id = value;
                }
            };

            let myRecevierObj = {
                id:10
            }
            console.log(myRecevierObj.id);  //10
            console.log(Reflect.set(obj,'id',9,myRecevierObj));  //true
            console.log(myRecevierObj.id);   //9
        }

        {
            let p = {
                a:'a'
            };

            let handler = {
                set(target, key, value, receiver){
                    console.log('set');
                    Reflect.set(target,key,value,receiver);
                },
                defineProperty(target,key,attributes){
                    console.log('defineProperty');
                    Reflect.defineProperty(target,key,attributes);
                }
            }

            let obj = new Proxy(p,handler);
            obj.a = 'A';
            console.log(obj.a);  //A
            //set
            //defineProperty
        }
    上面的代码中,proxy。set拦截使用了Reflect.set,导致触发了Proxy.definedProperty拦截。
  • 3.Reflect.has(obj,property)
 Reflect.has方法使用了对应name in Object 中的in运算符。
        {
            let obj = {
                name:'kjh'
            }

            //旧写法
            'name' in obj //true

            //新写法
            console.log(Reflect.has(obj,'name'));
            //true
        }
  • 4.Reflect.deleteProperty(obj,property)
    Reflect.deleteProperty(obj,property)用于删除对象的属性
  {
            let person = {
                name:'kjh'
            }

            //旧写法
            delete person.name;  //true

            //新写法
            console.log(Reflect.deleteProperty(person,'name'));
            //true
        }

  • 5.Reflect.construct(target,args)
    Reflect.construct(target,args) 等同于new target(…args)提供了一种不适用new来调用构造函数的方法
 {
            function sayName(name){
                this.name = name;
            }

            //new
            let instance = new sayName('zs');
            console.log(instance);
            //sayName {name: "zs"}

            //新方法
            let instance2 = Reflect.construct(sayName,['ls']);
            console.log(instance2);
            // /sayName {name: "ls"}

            //传入的第二个参数要是数组形式
        }
  • 6.Reflect.getPrototypeOf(obj)
    用于读取对象的proto属性, 对应Object.getPrototypeOf(obj)

  • 7.Reflect.setPrototypeOf(obj, newProto)
    设置目标对象的原型( prototype), 对应Object.setPrototypeOf(obj, newProto) 方法。

  • 8.Reflect.apply(func, thisArg, args)
    继承目标对象的特定方法

 {
            let args = [1,2,3,4,5,6];

            //旧写法
            let youngest = Math.min.apply(Math,ages);
            let oldest = Math.max.apply(Math,args);

            //新写法
            let youngest = Reflect.apply(Math.min,Math,args);
            let oldest = Reflect.apply(Math.max,Math,args);

        }

  • 9.Reflect.defineProperty(target, propertyKey, attributes)为对象定义属性。
{
            let person = {
                id:0
            }

            //旧写法
            Object.defineProperty(person,'name',{
                value:'小明'
            })

            //新写法
            Reflect.defineProperty(person,'age',{
                value:18
            })

            console.log(person);
            // /{id: 0, name: "小明", age: 18}
        }


  • 10.Reflect.getOwnPropertyDescriptor(target, propertyKey) 获取对象指定属性的描述对象
   {
            let person = {
                name:'kjh'
            }

            //旧写法
            console.log(Object.getOwnPropertyDescriptor(person,'name'));
            //{value: "kjh", writable: true, enumerable: true, configurable: true}

            //新写法
            console.log(Reflect.getOwnPropertyDescriptor(person,'name'));
            //{value: "kjh", writable: true, enumerable: true, configurable: true}

        }


    (11) Reflect.getOwnPropertyDescriptor(target, propertyKey)
    基本等同于Object.getOwnPropertyDescriptor, 用于得到指定属性的描述对象

    ( 12) Reflect.isExtensible(target)
    对应Object.isExtensible, 返回一个布尔值, 表示当前对象是否可扩展

    ( 13) Reflect.preventExtensions(target)
    对应Object.preventExtensions方法, 用于让一个对象变为不可扩展。 它返回一个布尔值, 表示是否操作成功

    ( 14) Reflect.ownKeys(target)
    用于返回对象的所有属性

4.proxy观察者模式。


 //使用Proxy实现观察者模式
        {
            function Person(name) {
                this.name = name;
            }

            let son = new Person('灰太狼');

            //proxy代理
            let changeNameValue = new Proxy(son, {
                set(target, property, value, receiver) {
                    if (property == 'name') {
                        console.log(`name 从 ${target[property]} 变为 ${value}`)
                    }
                    Reflect.set(target, property, value, receiver)
                }
            });

            changeNameValue.name = '喜羊羊';
            console.log(son);

            // name 从 灰太狼 变为 喜羊羊
            // Person {name: "喜羊羊"}
        }
  • 文档参考<ES6标准入门第三版(阮一峰)>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 设置代理 在ES6中,可以使用Proxy对象来设置代理。 Proxy对象是一个代理对象,它可以拦截并重定义基本操作,比如属性访问、赋值、函数调用等。通过Proxy对象可以实现对一个对象的代理访问,从而实现对该对象的控制。 使用Proxy对象时,需要传入两个参数:要代理的对象和一个处理程序对象。处理程序对象是一个包含各种捕捉器的对象,用于拦截基本操作。 下面是一个简单的例子,展示如何使用Proxy对象设置代理: ```javascript let target = {}; // 要代理的对象 let handler = { // 处理程序对象 get: function(target, prop) { // get捕捉器,拦截属性访问操作 console.log(`访问了属性 ${prop}`); return target[prop]; }, set: function(target, prop, value) { // set捕捉器,拦截属性赋值操作 console.log(`设置了属性 ${prop},新值为 ${value}`); target[prop] = value; return true; } }; let proxy = new Proxy(target, handler); // 创建代理对象 proxy.name = "Tom"; // 设置代理对象的属性 console.log(proxy.name); // 访问代理对象的属性 ``` 上面的代码中,我们使用了Proxy对象设置了一个代理对象。代理对象可以通过handler对象中的get和set捕捉器来拦截属性访问和赋值操作,并进行相应的处理。 2. 获取代理 在ES6中,可以使用Reflect对象的get方法来获取代理对象的属性值。 Reflect对象是一个内置对象,它提供了一组静态方法,用于操作对象。其中,Reflect.get方法可以用于获取对象的属性值。 下面是一个简单的例子,展示如何使用Reflect.get方法获取代理对象的属性值: ```javascript let target = { name: "Tom" }; // 要代理的对象 let handler = { // 处理程序对象 get: function(target, prop) { // get捕捉器,拦截属性访问操作 console.log(`访问了属性 ${prop}`); return target[prop]; } }; let proxy = new Proxy(target, handler); // 创建代理对象 console.log(Reflect.get(proxy, "name")); // 获取代理对象的属性值 ``` 上面的代码中,我们使用了Reflect.get方法获取了代理对象的属性值。这个方法接收两个参数:要获取属性值的对象和属性名。在这个例子中,我们传入了代理对象和属性名,从而获取了代理对象的属性值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值