Reflect概述
Reflect是ES6提供的操作对象的Api,其主要目的有
- 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从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对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。
Reflect静态方法
- Reflect.get(target,name,receiver):查找并返回target对象的name属性,如果没有该属性返回undefined
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| var myObject = { foo: 1, bar: 2, get baz() { return this.foo + this.bar; }, }
var myReceiverObject = { foo: 4, bar: 4, };
Reflect.get(myObject, 'foo') Reflect.get(myObject, 'bar') Reflect.get(myObject, 'baz')
Reflect.get(myObject, 'baz', myReceiverObject)
|
- Reflect.set(target,name,value,receiver):设置对象的name属性值为value
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var myObject = { foo: 4, set bar(value) { return this.foo = value; }, };
var myReceiverObject = { foo: 0, };
Reflect.set(myObject, 'bar', 1, myReceiverObject); myObject.foo myReceiverObject.foo
|
- Reflect.has(obj,name):判断obj对象是否包含name属性
1 2 3 4 5 6 7 8
| var myObject = { foo: 1, };
'foo' in myObject
Reflect.has(myObject, 'foo')
|
- Reflect.deleteProperty(obj, name):等同于delete obj[name]方法,删除对象的name属性值
1 2 3 4 5 6
| const myObj = { foo: 'bar' };
delete myObj.foo;
Reflect.deleteProperty(myObj, 'foo');
|
- Reflect.construct(target,args):等同于new target(…args)提供了一种不使用new调用构造函数的方法。
1 2 3 4 5 6 7 8
| function Greeting(name) { this.name = name; }
const instance = new Greeting('张三');
const instance = Reflect.construct(Greeting, ['张三']);
|
- Reflect.apply(func,thisArg,args):等同于Function.prototype.apply.call(func,thisArg,args)用于绑定this对象后执行给定函数。
1 2 3 4 5 6 7 8 9 10 11
| const ages = [11, 33, 12, 54, 18, 96];
const youngest = Math.min.apply(Math, ages); const oldest = Math.max.apply(Math, ages); const type = Object.prototype.toString.call(youngest);
const youngest = Reflect.apply(Math.min, Math, ages); const oldest = Reflect.apply(Math.max, Math, ages); const type = Reflect.apply(Object.prototype.toString, youngest, []);
|
- Reflect.ownKeys(target):返回对象的所有属性,等同于Object.getOwnPropertyNames与Object.getOwnPropertySymbols之和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| var myObject = { foo: 1, bar: 2, [Symbol.for('baz')]: 3, [Symbol.for('bing')]: 4, };
Object.getOwnPropertyNames(myObject)
Object.getOwnPropertySymbols(myObject)
Reflect.ownKeys(myObject)
|
实例:使用Proxy和Reflect实现观察者模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const person = observable({ name: '张三', age: 20 });
function print() { console.log(`${person.name}, ${person.age}`) }
observe(print); person.name = '李四';
|
实现:
1 2 3 4 5 6 7 8 9 10
| const queuedObservers = new Set();
const observe = fn => queuedObservers.add(fn); const observable = obj => new Proxy(obj, {set});
function set(target, key, value, receiver) { const result = Reflect.set(target, key, value, receiver); queuedObservers.forEach(observer => observer()); return result; }
|