Reflect
Reflect
是 ES6 为了操作对象而提供的新 API。ES6把原先版本中很多语言层面的API,比如Object.defineProperty
delete
in
等集中在了Reflect
的静态方法上,引入Reflect
的目的有这样几个。
-
将
Object
对象的一些明显属于语言内部的方法(比如Object.defineProperty
),放到Reflect
对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect
对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。 -
修改某些
Object
方法的返回结果,让其变得更合理。
// 老写法
try {
Object.defineProperty(target, property, attributes);
// success
} catch (e) {
// failure
}
// 新写法
if (Reflect.defineProperty(target, property, attributes)) {
// success
} else {
// failure
}
- 将命令式操作转变为函数调用,避免更多的保留字占用。比如
name in obj
和delete
obj[name]
,对应Reflect.has(obj, name)
和Reflect.deleteProperty(obj, name)
// 老写法
'assign' in Object // true
// 新写法
Reflect.has(Object, 'assign') // true
Reflect
对象的方法与Proxy
对象的方法一一对应,想要调用默认行为,直接在Reflect上调用同名方法,简单可靠,省去人工写默认行为的代码。
let proxy = new Proxy({}, {
set: function(target, name, value, receiver) {
var success = Reflect.set(target, name, value, receiver);
if (success) {
console.log('property ' + name + ' on ' + target + ' set to ' + value);
}
return success;
}
});
Reflect对象的方法
Reflect对象一共有 13 个静态方法。
- Reflect.apply(target, thisArg, args)
- Reflect.construct(target, args)
- Reflect.get(target, name, receiver)
- Reflect.set(target, name, value, receiver)
- Reflect.defineProperty(target, name, desc)
- Reflect.deleteProperty(target, name)
- Reflect.has(target, name)
- Reflect.ownKeys(target)
- Reflect.isExtensible(target)
- Reflect.preventExtensions(target)
- Reflect.getOwnPropertyDescriptor(target, name)
- Reflect.getPrototypeOf(target)
- Reflect.setPrototypeOf(target, prototype)
上面这些方法的作用,与Proxy对象handler的方法是一一对应的。
应用
- 在某个属性被访问时,对返回值进行修饰
const target = {
foo: 'bar',
baz: 'qux'
}
const handler = {
get(trapTarget, property, receiver) {
let decoration = ''
if (property === 'foo') {
decoration = '!!!'
}
return Reflect.get(...arguments) + decoration
}
}
const proxy = new Proxy(target, handler)
console.log(proxy.foo) // bar!!!
console.log(target.foo) // bao
console.log(proxy.baz) // qux
console.log(target.baz) // qux