ES6中Reflect对象使用详解(附代码)

本文详细介绍了ES6中的Reflect对象,包括Reflect.get、Reflect.set、Reflect.has、Reflect.deleteProperty等方法的使用,阐述了Reflect对象如何提供对对象操作的函数行为,并讨论了其在对象扩展和属性管理中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

目录

Reflect的方法

 Reflect.get(target, name, receiver)

Reflect.set(target, name, value, receiver)

Reflect.has(obj, name)

Reflect.deleteProperty(obj, name)

Reflect.ownKeys (target)

Reflect.preventExtensions(target)

Reflect.isExtensible (target)

Reflect.defineProperty(target, propertyKey, attributes)

Reflect.getOwnPropertyDescriptor(target, propertyKey)

Reflect.apply(func, thisArg, args)


概述

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

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

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

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

4.Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。

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)

 Reflect.get(target, name, receiver)

Reflect.get(target, name, receiver)

Reflect.get方法查找并返回target对象的name属性,如果没有该属性,则返回undefined。

如果name属性部署了读取函数(getter),则读取函数的this绑定receiver。

    <script>
        // Reflect.get(target, name, receiver)
        // Reflect.get方法查找并返回target对象的name属性,如果没有该属性,则返回undefined。

        let obj = {
            name: '再努力些吧',
            age: 18,
            work: '前端',
            get baz() {
                return this.name + '的' + this.age;
            },

        }
        console.log(Reflect.get(obj, 'name'));//再努力些吧
        console.log(Reflect.get(obj, 'age'));//18
        console.log(Reflect.get(obj, 'work'));//前端
        console.log(Reflect.get(obj, 'sex'));//undefined

        // 如果name属性部署了读取函数(getter),则读取函数的this绑定receiver。

        let newObj = {
            name: '不能摆烂',
            age: 28
        }

        console.log(Reflect.get(obj, 'baz', newObj));//不能摆烂的28


    </script>

Reflect.set(target, name, value, receiver)

注意:Reflect.set,方法用法复杂,我只是简单展示用法,具体详细的建议去 阮一峰的ES6 去看

Reflect.set(target, name, value, receiver)

Reflect.set方法设置target对象的name属性等于value。

如果name属性设置了赋值函数,则赋值函数的this绑定receiver。

    <script>

        // Reflect.set(target, name, value, receiver)
        // Reflect.set方法设置target对象的name属性等于value。
        let obj = {
            name: '再努力些吧',
            age: 18,
            work: '前端',
            set baz(value) {
                return this.age = value
            },

        }




        Reflect.set(obj, 'name', '今天努力了吗')
        console.log(obj.name);//今天努力了吗


        // 如果name属性设置了赋值函数,则赋值函数的this绑定receiver。

        let newObj = {
            name: '不能摆烂',
            age: 28
        }

        Reflect.set(obj, 'age', 15, newObj)

        console.log(obj.age);//18
        console.log(newObj.age);//15

    </script>

Reflect.has(obj, name)

Reflect.has方法对应name in obj里面的in运算符。

如果Reflect.has()方法的第一个参数不是对象,会报错。

<script>

        // Reflect.has(obj, name)
        // Reflect.has方法对应name in obj里面的in运算符。
        // 如果Reflect.has()方法的第一个参数不是对象,会报错。
        let obj = {
            name: '再努力些吧',
            age: 18,
            work: '前端',


        }
        // 旧写法
        console.log('age' in obj);//true
        console.log('sex' in obj);//false
        // 新写法
        console.log(Reflect.has(obj, 'age'));//true
        console.log(Reflect.has(obj, 'sex'));//false

</script> 

Reflect.deleteProperty(obj, name)


Reflect.deleteProperty方法等同于delete obj[name],用于删除对象的属性。

该方法返回一个布尔值。如果删除成功,或者被删除的属性不存在,返回true;删除失败,被删除的属性依然存在,返回false。

如果Reflect.deleteProperty()方法的第一个参数不是对象,会报错。

  <script>

        // Reflect.deleteProperty(obj, name)
        // Reflect.deleteProperty方法等同于delete obj[name],用于删除对象的属性。

        // 该方法返回一个布尔值。如果删除成功,或者被删除的属性不存在,返回true;删除失败,被删除的属性依然存在,返回false。

        // 如果Reflect.deleteProperty()方法的第一个参数不是对象,会报错。

        let obj = {
            name: '再努力些吧',
            age: 18,
            work: '前端',


        }

        // 旧写法
        // delete obj.age
        // console.log(obj);//{name: '再努力些吧', work: '前端'}

        // 新写法
        console.log(Reflect.deleteProperty(obj, 'name'));//true
        console.log(obj);//{age: 18, work: '前端'}


    </script>

Reflect.ownKeys (target)

Reflect.ownKeys方法用于返回对象的所有属性,基本等同于Object.getOwnPropertyNames与Object.getOwnPropertySymbols之和

<script>

        // Reflect.ownKeys (target) 
        // Reflect.ownKeys方法用于返回对象的所有属性,基本等同于Object.getOwnPropertyNames与Object.getOwnPropertySymbols之和

        let myObject = {
            foo: 1,
            bar: 2,
            [Symbol.for('baz')]: 3,
            [Symbol.for('bing')]: 4,
        };


        //旧写法

        //获取对象中除了symbol之外的对象的所有属性
        console.log(Object.getOwnPropertyNames(myObject));//['foo', 'bar']

        //获取对象中symbol的对象的所有属性
        console.log(Object.getOwnPropertySymbols(myObject));//[Symbol(baz), Symbol(bing)]

        // 新写法

        // 获取所有属性
        console.log(Reflect.ownKeys(myObject));// ['foo', 'bar', Symbol(baz), Symbol(bing)]

</script>

Reflect.preventExtensions(target)

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


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

        let myObject = {}


        // 旧写法
        console.log(Object.preventExtensions(myObject));//{}


        // 新写法
        console.log(Reflect.preventExtensions(myObject));//true


          // 如果参数不是对象,Object.preventExtensions在 ES5 环境报错,在 ES6 环境返回传入的参数,而Reflect.preventExtensions会报错。


// ES5 环境
// Object.preventExtensions(1) // 报错

// ES6 环境
// Object.preventExtensions(1) // 1

// 新写法

// Reflect.preventExtensions(1) // 报错

</script> 

Reflect.isExtensible (target)

Reflect.isExtensible方法对应Object.isExtensible,返回一个布尔值,表示当前对象是否可扩展。

如果参数不是对象,Object.isExtensible会返回false,因为非对象本来就是不可扩展的,而Reflect.isExtensible会报错。

<script>
        // Reflect.isExtensible (target)
        // Reflect.isExtensible方法对应Object.isExtensible,返回一个布尔值,表示当前对象是否可扩展。

        let myObject = {}

        // 旧写法

        console.log(Object.isExtensible(myObject));//true

        // 新写法

        console.log(Reflect.isExtensible(myObject));//true

        // 如果参数不是对象,Object.isExtensible会返回false,因为非对象本来就是不可扩展的,而Reflect.isExtensible会报错。

        console.log(Object.isExtensible(1));// false
        console.log(Reflect.isExtensible(1));// 报错
</script>

Reflect.defineProperty(target, propertyKey, attributes)

Reflect.defineProperty方法基本等同于Object.defineProperty,用来为对象定义属性。未来,后者会被逐渐废除,请从现在开始就使用Reflect.defineProperty代替它。

<script>
        // Reflect.defineProperty(target, propertyKey, attributes)
        // Reflect.defineProperty方法基本等同于Object.defineProperty,用来为对象定义属性。未来,后者会被逐渐废除,请从现在开始就使用Reflect.defineProperty代替它。

        let myObject = {}

        // 旧写法
        Object.defineProperty(myObject, "name", {
            enumerable: false,
            configurable: false,
            writable: false,
            value: "再努力些把"
        });
        console.log(myObject);//{name: '再努力些把'}

        // 新写法
        Reflect.defineProperty(myObject, 'now', {
            value: () => Date.now()
        });
        console.log(myObject);//{name: "再努力些把"  now: () => Date.now()}
        console.log(myObject.now());//1660548733267
        // 如果Reflect.defineProperty的第一个参数不是对象,就会抛出错误,比如 
          Reflect.defineProperty(1, 'foo')。
</script>

Reflect.getOwnPropertyDescriptor(target, propertyKey)

Reflect.getOwnPropertyDescriptor基本等同于Object.getOwnPropertyDescriptor,用于得到指定属性的描述对象,将来会替代掉后者。

<script>
        // Reflect.getOwnPropertyDescriptor(target, propertyKey)
        // Reflect.getOwnPropertyDescriptor基本等同于Object.getOwnPropertyDescriptor,用于得到指定属性的描述对象,将来会替代掉后者。

        var myObject = {};
        Object.defineProperty(myObject, 'hidden', {
            value: true,
            enumerable: false,
        });
        Reflect.defineProperty(myObject, 'now', {
            value: () => Date.now()
        });

        // 旧写法
        var theDescriptor = Object.getOwnPropertyDescriptor(myObject, 'hidden');
        //{value: true, writable: false, enumerable: false, configurable: false}

        console.log(theDescriptor);

        // 新写法
        var theDescriptor = Reflect.getOwnPropertyDescriptor(myObject, 'now');
        //{writable: false, enumerable: false, configurable: false, value: ƒ}
        console.log(theDescriptor);
        // Reflect.getOwnPropertyDescriptor和Object.getOwnPropertyDescriptor的一个区别是,如果第一个参数不是对象,
        // Object.getOwnPropertyDescriptor(1, 'foo')不报错,返回undefined,而
        // Reflect.getOwnPropertyDescriptor(1, 'foo')会抛出错误,表示参数非法。
    </script>

Reflect.apply(func, thisArg, args)

Reflect.apply方法等同于Function.prototype.apply.call(func, thisArg, args),用于绑定this对象后执行给定函数。

一般来说,如果要绑定一个函数的this对象,可以这样写fn.apply(obj, args),但是如果函数定义了自己的apply方法,就只能写成Function.prototype.apply.call(fn, obj, args),采用Reflect对象可以简化这种操作。

<script>
        // Reflect.apply(func, thisArg, args)
        // Reflect.apply方法等同于Function.prototype.apply.call(func, thisArg, args),用于绑定this对象后执行给定函数。

        // 一般来说,如果要绑定一个函数的this对象,可以这样写fn.apply(obj, args),但是如果函数定义了自己的apply方法,就只能写成Function.prototype.apply.call(fn, obj, args),采用Reflect对象可以简化这种操作。

        const ages = [11, 33, 12, 54, 18, 96];

        // 旧写法
        const youngest = Math.min.apply(Math, ages);
        const oldest = Math.max.apply(Math, ages);
        const type = Object.prototype.toString.call(youngest);


        // 新写法
        // const youngest = Reflect.apply(Math.min, Math, ages);
        // const oldest = Reflect.apply(Math.max, Math, ages);
        // const type = Reflect.apply(Object.prototype.toString, youngest, []);



        console.log(youngest); //11
        console.log(oldest); //96
        console.log(type); //[object Number]
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值