【ES6系列】Reflect

概述

Reflect 是为了操作对象而提供的 API,它的设计目的有以下几个。

  • Object 上一些属于语言内部的方法 (比如 Object.defineProperty)放在 Reflect 对象上。现阶段,某些方法同时在 ObjectRelfect 对象上部署,未来的新方法将只部署在 Reflect 对象上。
  • 修改某些 Object 方法的返回结果,让其更加完善。比如,Object.defineProperty(obj,name,desc) 在无法定义属性时,会抛出一个异常,而 Reflect.defineProperty(obj,name,desc) 则会返回 false
  • Object 操作变成函数行为。某些 Object 操作是命令式的,比如 name in objdelete obj[name] ,而 Reflect.has(obj,name)Reflect.deleteProperty(obj,name) 让他们变成了函数行为。
  • Reflect 对象的方法与 Proxy 对象的方法对应,只要是 Proxy 对象的方法,就能在 Reflect 对象上找到对应的方法。这就让 Proxy 对象可以方便的调用对应的方法,完成默认行为。也就是说,不管 Proxy 怎么修改默认行为,你总可以在 Reflect 上获取默认行为。

静态方法

Reflect 对象上一共有13个静态方法,这些大部分与 Object 对象同名甚至作用都是相同的,而且它与 Proxy 对象的方法是对应的。

Reflect.get(target,name,receiver)

Reflect.get() 方法查找并返回 target 对象的 name 属性,如果没有该属性,则返回 undefined。如果 name 属性部署了 getter ,那么将 receiver 绑定到函数中的 this

let person = {
    name:"jonas",
    get age(){
        return this.age
    }
}

let jonas = {age:18}

let name = Reflect.get(person,"name")
let age = Reflect.get(person,"age",jonas)
console.log(name) //jonas
console.log(age) //18

另外,如果第一个参数不是对象,而是基本类型数据,则会报错。

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

设置 target 对象的 name 属性为 value ,如果属性设置了 setter 则将 receiver 绑定到函数中的 this

let person = {
    name:"jonas",
    get age(){
        return this.age
    },
    set age(value){
        return this.age = value
    }
}

let jonas = {age:18}

Reflect.set(person,"age",20,jonas)

console.log(jonas.age) //20

同样的,如果第一个参数不是对象,则会报错。

Reflect.has(obj,name)

判断 name 是否为 obj 对象中的属性,相当于 name in obj 。方法返回布尔值。

let person = {name:"jonas"}
let result = Reflect.has(person,"name")
console.log(result) //true

Reflect.deleteProperty(obj,name)

删除对象中的属性,相当于 delete obj[name],该方法返回布尔值,如果属性不存在或删除成功,则返回 true

let person = {name:"jonas"}
let result = Reflect.deleteProperty(person,"name")
console.log(result) //true
console.log(person) ///{}

Reflect.construct(target,args)

该方法等同于 new 运算符,提供了一种不使用 new 关键字实例化的方式。其中 target 是构造函数,args 则是函数的参数列表。

function Person(name,age){
    this.name = name
    this.age = age
}

let person = Reflect.construct(Person,["jonas",18])
console.log(person) //Person { name: 'jonas', age: 18 }

Reflect.getPrototypeOf(obj)

用于读取对象的 __proto__ 属性,对应 Object.getPrototypeOf(obj)

Reflect.getPrototypeOf()Object.getPrototypeOf() 的区别是后者如果第一个参数不是对象,则会转换为对象,而前者会报错。

Reflect.setPrototypeOf(obj,proto)

该方法用于设置目标对象的原型,与 Object.setPrototypeOf() 对应,返回值是一个布尔值,表示是否设置成功。

提点:封闭对象,无法扩展对象,冻结对象不能设置原型。

如果第一个参数不是,这两个方法都会报错。

Reflect.apply(func,thisArg,args)

该方法等同于 Function.prototype.apply.call() 用于绑定 this 对象后执行函数。

一般情况下,如果需要绑定函数 this,可以直接 fn.call(),但是如果函数重写了 apply() 方法,就只能通过 Function 的原型来实现了。然而,Reflect 就是简化了这个操作。

Reflect.defineProperty(target,key,desc)

该方法等同于 Object.defineProperty,用来为对象定义属性。注意:Object.defineProperty 将逐渐被淘汰,取而代之的是 Reflect.defineProperty .

Reflect.getOwnPropertyDescriptor(target,prop)

该方法基本等同于 Object.getOwnPropertyDescriptor() ,用于得到指定属性的属性描述符,将来后者将会被废除。

Reflect.isExtensible(target)

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

Reflect.preventExtensions(target)

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

Reflect.ownKeys(target)

该方法用于返回对象的所有属性,等于 Object.getOwnPropertyNamesObject.getOwnPropertySymbols 两者之和。

【ES6系列】Reflect【ES6系列】Reflect jonas_von 发布了107 篇原创文章 · 获赞 1 · 访问量 5709 私信 关注
上一篇:golang 之反射


下一篇:常用ES6-ES10知识点总结