Reflect 是 ES2015中提供的一种全新的内置对象,如果按照 Java 或者 C# 这类语言的说法,Reflect 属于一个静态类,也就是说它不能够通过 new 的方式去构建一个实例对象,只能够去调用这个静态类当中的静态方法。这一点应该不陌生,因为在 JS 中的 Math 对象也是相同的。在 Reflect 内部封装了一系列对对象的底层操作,具体一共提供了14个静态方法其中又一个被废弃掉了还剩下13个。仔细去查看 Reflect 文档你会发现这13个方法的方法名与 Proxy 对象中的处理对象方法成员是完全一致的。其实,Reflect 成员方法就是 Proxy 处理对象的默认实现。在 Proxy 处理对象中可以添加不同的方法成员来去监听对象所对应的操作,如果说没有添加具体的处理方法,它内部默认实现的逻辑就是调用了 Reflect 对象当中所对应的方法。这也就表明我们在去实现自定义的 get 或 set 这样的逻辑时,更标准的做法就是先去实现自己所需要的监视逻辑,最后再去返回通过 Reflect 中对应的方法的一个调用结果。
const obj = {
foo: '123',
bar: '456',
};
const proxy = new Proxy(obj, {
get (target, property) {
return Reflect.get(target, property)
},
set (target, property, value) {
return Reflect.set()
}
})
Reflect 的价值体现在:统一提供一套用于操作对象的 API 。
const obj = {
name: 'zce',
age: 18,
}
// 判断 obj 中是否包含 name 属性
'name' in obj <==> Reflect.has(obj, 'name')
// 删除 obj 的 age 属性
delete obj['age'] <==> Reflect.deletePropery(obj, 'age')
// 获取 obj 的所有的属性名
Object.keys(obj) <==> Reflect.ownKeys(obj)
Reflect.apply(target, thisArgument, argumentsList)对一个函数进行调用操作,同时可以传入一个数组作为调用参数。和Function.prototype.apply()功能类似;Reflect.construct(target, argumentsList[, newTarget])对构造函数进行 new 操作,相当于执行new target(...args);Reflect.defineProperty(target, propertyKey, attributes)和Object.defineProperty()类似。如果设置成功就会返回 true;Reflect.deleteProperty(target, propertyKey)作为函数的delete操作符,相当于执行delete target[name];Reflect.get(target, propertyKey[, receiver])获取对象身上某个属性的值,类似于target[name];Reflect.getOwnPropertyDescriptor(target, propertyKey)类似于Object.getOwnPropertyDescriptor()。如果对象中存在该属性,则返回对应的属性描述符, 否则返回undefined;Reflect.getPrototypeOf(target)类似于 Object.getPrototypeOf();- Reflect.has(target, propertyKey) 判断一个对象是否存在某个属性,和 in 运算符 的功能完全相同;
Reflect.isExtensible(target)类似于Object.isExtensible();Reflect.ownKeys(target)返回一个包含所有自身属性(不包含继承属性)的数组。(类似于Object.keys(), 但不会受enumerable影响);Reflect.preventExtensions(target)类似于Object.preventExtensions()。返回一个Boolean;Reflect.set(target, propertyKey, value[, receiver])将值分配给属性的函数。返回一个Boolean,如果更新成功,则返回true;Reflect.setPrototypeOf(target, prototype)设置对象原型的函数. 返回一个Boolean, 如果更新成功,则返回true;