Reflect对象浅析

一、什么是reflect对象

  Reflect对象是一个全局的普通的对象。Reflect的原型就是Object。

  我们首先来验证下 看看Reflect的原型是否是Object, 基本代码如下:

let obj = {};
console.log(Reflect.__proto__ === Object.prototype); // true
console.log(obj.__proto__ === Reflect.__proto__); // true

  Reflect是ES6为了操作对象而新增的API, 为什么要添加Reflect对象呢?它这样设计的目的是为了什么?

1、将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上,那么以后我们就可以从Reflect对象上可以拿到语言内部的方法。

2、在使用对象的 Object.defineProperty(obj, name, {})时,如果出现异常的话,会抛出一个错误,需要使用try catch去捕获,但是使用 Reflect.defineProperty(obj, name, desc) 则会返回false

try {
  Object.defineProperty(target, property, attributes);
  // success
} catch (e) {
  // failure
}
// 新写法
if (Reflect.defineProperty(target, property, attributes)) {
  // success
} else {
  // failure
}

  让Object操作变成函数行为

'name' in Object //true
// 新写法
Reflect.has(Object,'name') //true

  Reflect与Proxy是相辅相成的,在Proxy上有的方法,在Reflect就一定有

    let target={}
    let handler={
      set(target,proName,proValue,receiver){
        //确认对象的属性赋值成功
        let isSuccess=Reflect.set(target,proName,proValue,receiver)
        if(isSuccess){
          console.log("成功")
        }
        return isSuccess
      }
    }
    let proxy=new Proxy(target,handler)

  确保对象的属性能正确赋值,广义上讲,即确保对象的原生行为能够正常进行,这就是Reflect的作用

二、Reflect的API

  注:由于和Proxy的API一致,所以参数就不解释了。

1、Reflect.get(target,property,receiver):查找并返回target对象的property属性

    let obj={
      //属性yu部署了getter读取函数
      get yu(){
        //this返回的是Reflect.get的receiver参数对象
        return this.name+this.age
      }
    }

    let receiver={
      name:"shen",
      age:"18",
    }
    
    let result=Reflect.get(obj,"yu",receiver)
    console.log(result) //shen18

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

2、Reflect.set(target,propName,propValue,receiver):设置target对象的propName属性为propValue

    let obj={
      name:"chen"
    }

    let result=Reflect.set(obj,"name","shi")
    console.log(result) //true
    console.log(obj.name) //shi
    let obj={
      age:38,
      set setAge(value){
        return this.age=value
      }
    }

    let receiver={
      age:28
    }

    let result=Reflect.set(obj,"setAge",18,receiver)
    console.log(result) //true
    console.log(obj.age) //38
    console.log(receiver.age) //18

3、Reflect.has(obj,name)

4、Reflect.deleteProperty(obj, name):删除对象的属性

delete obj.name;

Reflect.deleteProperty(obj, 'name');

5、Reflect.construct(target, args)

function Person(name) {
  this.name = name;
}
let person= new Person('chen')

let person = Reflect.construct(Person, ['chen']);

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 array=[1,2,3,4,5,6]
let small= Math.min.apply(Math, array) //1
let big = Math.max.apply(Math, array) //6

// 新写法
const small= Reflect.apply(Math.min, Math, array)
const big = Reflect.apply(Math.max, Math, array)

9、Reflect.defineProperty(target, propertyKey, attributes)

Reflect.defineProperty(MyDate, 'now', {
  value: () => Date.now()
});

  与Proxy.defineProperty配合使用

let proxy = new Proxy({}, {
  defineProperty(target, prop, descriptor) {
    console.log(descriptor);
    return Reflect.defineProperty(target, prop, descriptor);
  }
});

proxy .name= 'chen';
// {value: "chen", writable: true, enumerable: true, configurable: true}
p.name // "chen"

  Proxy.defineProperty对属性赋值设置拦截,然后使用Reflect.defineProperty完成赋值

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

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

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

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

posted @ 2020-05-18 23:05  古兰精  阅读(626)  评论(0编辑  收藏  举报