Reflect
Reflect 对象和Proxy对象一样, 为操作对象提供了新的API。
为什么使用 Reflect的方式来操作对象?
-
将 Object 对象上一些明显属于内部的方法放到 Reflect对象上。比如
Object.defindProperty
也可以使用Reflect.defindProperty
-
修改某些 Object 方法的返回结果
-
让 Object 操作都变成函数行为。
-
Reflect 对象的操作方法和 Proxy的方法一一对应, 很方便 Proxy对象来调用 Reflect 方法
例子:
const sum = function (num1, num2) {return num1 + num2}const proxy = new Proxy(sum, {apply(target, context, args) {return Reflect.apply(...arguments) * 2}})proxy(1,2) // 6
以上代码 proxy 的配置方法 apply和 Reflect的apply方法是对应关系,直接通过 Reflect.apply
来调用拦截函数 sum
。并将函数执行后的结果 * 2。最终的结果是 6。
#### Reflect 对象和 Proxy的静态方法一样,同样是13个。
- Reflect.apply(target, context, args)
- Reflect.get(target, key, context)
- Reflect.set(target, key, value, context)
- Reflect.construct(target, args)
- Reflect.defindProperty(target, key, desc)
- Reflect.has(target, key)
- Reflect.deleteProperty(target, key)
- Reflect.setProperty(target, proto)
- Reflect.getProperty(target)
- Reflect.ownKeys(target)
- Reflect.isExtensible(target)
- Reflect.preventExtensions(target)
- Reflect.getOwnPropertyDescriptor(target, key)
Reflect.get(target, key, context)
target
: 查找的对象key
: 查找的属性context
: 读取getter函数的上下文对象
const obj = {name: 'qiqingfu',get sayName() {console.log(this.name)}}const obj1 = {name: 'zhangfei'}Reflect.get(obj, 'name') // qiqingfu Reflect.get(obj, 'sayName', obj1) // zhangfei
如果第一个参数不是对象, Reflect.get
方法会报错。
Reflect.set(target, key, value, context)
target
: 要给哪个对象设置key
: 要设置的属性value
: 设置的值返回值
: boolean
const obj = {value: 1,set fn(newValue) {return this.value = newValue}} console.log(Reflect.set(obj, 'name', 'qiqingfu')) // trueconsole.log(Reflect.set(obj, 'fn', 2))console.log(obj)
以上代码,给obj对象设置了一个name
属性,其值为qiqingfu
, 并且设置fn
的时候被get
函数拦截到了。
Reflect.has(target, key) 方法检测 target对象上有么有 key这个属性
返回值
: boolean
const obj = {name: 'qiqingfu',a: 2}console.log(Reflect.has(obj, 'name')) // trueconsole.log(Reflect.has(obj, 'a')) // trueconsole.log(Reflect.has(obj, 'b')) // false
其实 Reflect.has
和 in
操作符类似。
Reflect.construct(target, args) 方法用于类似于 new 操作符
target
: 目标函数args
: 实例化对象需要传递的参数 Array返回值
: 实例对象
function Prosen (name, age) {this.name = name;this.age = age}const prosen = Reflect.construct(Prosen, ['qiqingfu', 22])// {name: 'qiqingfu', age: 22}
以上代码使用 Reflect.construct
方法实例话一个对象,接受的参数为数组类型
Reflect.defineProperty(target, key, decs) 和 Object.defineProperty(target, key, decs) 一样
更推崇使用前者。
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
const obj = {}Reflect.defineProperty(obj, 'a', {value: 1,configurable: true, // 可配置writable: true // 可写})// {a: 1}
以上代码给 obj 对象添加了一个 a属性, 其值为1并且是可配置和可修改的
Reflect.deleteProperty(target, key) 方法删除 target对象的key属性
const obj = {a: 1}Reflect.defindProperty(obj, 'a')console.log(obj) // {}
Reflect.getPropertyOf(target) 方法获取一个对象的原型对象
function Prosen() {}Prosen.prototype.age = 21const prosen = Reflect.construct(Prosen, [])// 获取原型对象的属性 const proto = Reflect.getPrototypeOf(prosen)console.log(proto)// {age: 21, constructor: ƒ}
以上代码 给 Prosen 构造函数的原型对象上添加了一个 age属性。并且通过 Reflect.construct
方法实例化一个对象。那么就可以通过 Reflect.getPrototypeOf
方法获取一个对象的原型对象。
Reflect.setPrototypeOf(target, proto) 方法将 proto设置为 target对象的原型对象
function Prosen() {}Prosen.prototype.age = 21const prosen = Reflect.construct(Prosen, [])// 设置prosen 的原型对象Reflect.setPrototypeOf(prosen, {b: 2})
此时, prosen的原型对象为 {b:2}, 而 construct
指针会被覆盖
Reflect.ownKeys(target) 获取对象的key值,返回值为数组
和 Object.ownKeys
相同。
const obj = {a: 1,[Symbol('c')]: 3,}Reflect.defineProperty(obj, 'b', {value: 2,configurable: true,enumerable: true})console.log(Reflect.ownKeys(obj))// ["a", "b", Symbol(c)]
返回值是一个数组, 存放着对象的 key值的集合。
Reflect.getOwnPropertyDescriptor(target, key) 方法获取一个对象key值的描述对象
返回值
: Object
const obj = {a: 1,[Symbol('c')]: 3,}Reflect.defineProperty(obj, 'b', {value: 2,configurable: true,enumerable: true})const decs = Reflect.getOwnPropertyDescriptor(obj, 'b')console.log(decs)/*{value: 2, writable: false, enumerable: true, configurable: true}*/
以上代码通过 Reflect.getOwnPropertyDescriptor
方法获取一个对象属性的描述对象, 如果第一个参数不是对象会报错。而在 Object.getOwnPropertyDescriptor
不会报错,只不过返回 undefind
转载于:https://www.cnblogs.com/qiqingfu/p/10013336.html