概述
Reflect
是为了操作对象而提供的 API
,它的设计目的有以下几个。
- 将
Object
上一些属于语言内部的方法 (比如Object.defineProperty
)放在Reflect
对象上。现阶段,某些方法同时在Object
和Relfect
对象上部署,未来的新方法将只部署在Reflect
对象上。 - 修改某些
Object
方法的返回结果,让其更加完善。比如,Object.defineProperty(obj,name,desc)
在无法定义属性时,会抛出一个异常,而Reflect.defineProperty(obj,name,desc)
则会返回false
- 让
Object
操作变成函数行为。某些Object
操作是命令式的,比如name in obj
和delete 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.getOwnPropertyNames
与 Object.getOwnPropertySymbols
两者之和。