ES6 (7):Reflect

Reflect 配合proxy  使对象的操做更加函数化。javascript

大部分Reflect 的全局方法或者说静态方法与proxy一致。java

相比Object  返回值更合理:修改某些Object方法的返回结果,让其变得更合理。好比,Object.defineProperty(obj, name, desc)在没法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回falseapp

 

若是 Proxy对象和 Reflect对象联合使用,前者拦截赋值操做,后者完成赋值的默认行为,并且传入了receiver,那么Reflect.set会触发Proxy.defineProperty拦截。函数

let p = {
  a: 'a'
};

let handler = {
  set(target, key, value, receiver) {
    console.log('set');
    Reflect.set(target, key, value, receiver)
  },
  defineProperty(target, key, attribute) {
    console.log('defineProperty');
    Reflect.defineProperty(target, key, attribute);
  }
};

let obj = new Proxy(p, handler);
obj.a = 'A';
// set
// defineProperty

 由于Proxy.setreceiver参数老是指向当前的 Proxy实例(即上例的obj),而Reflect.set一旦传入receiver,就会将属性赋值到receiver上面(即obj),致使触发defineProperty拦截。若是Reflect.set没有传入receiver,那么就不会触发defineProperty拦截。this

 

 

Reflect.construct: 等同于new  target(args) 建立实例对象。spa

function Greeting(name) {
  this.name = name;
}

// new 的写法
const instance = new Greeting('张三');

// Reflect.construct 的写法
const instance = Reflect.construct(Greeting, ['张三']);

 若是Reflect.construct()方法的第一个参数不是函数会报错prototype

 

Reflect.getPrototypeOf:用于读取对象的__proto__属性,对应Object.getPrototypeOf(obj)代理

const myObj = new FancyThing();

// 旧写法
Object.getPrototypeOf(myObj) === FancyThing.prototype;

// 新写法
Reflect.getPrototypeOf(myObj) === FancyThing.prototype;

 Reflect.getPrototypeOfObject.getPrototypeOf的一个区别是,若是参数不是对象,Object.getPrototypeOf会将这个参数转为对象,而后再运行,而Reflect.getPrototypeOf会报错code

 

 

Reflect.apply(): 若是要绑定一个函数的this对象,能够这样写fn.apply(obj, args),可是若是函数定义了本身的apply方法,就只能写成Function.prototype.apply.call(fn, obj, args),采用Reflect对象能够简化这种操做。server

 

Reflect.defineProperty:为对象定义属性

const p = new Proxy({}, {
  defineProperty(target, prop, descriptor) {
    console.log(descriptor);
    return Reflect.defineProperty(target, prop, descriptor);
  }
});

p.foo = 'bar';
// {value: "bar", writable: true, enumerable: true, configurable: true}

p.foo // "bar"

 Proxy.defineProperty对属性赋值设置了拦截,而后使用Reflect.defineProperty完成了赋值

 

 

Reflect.preventExtensions:用于让一个对象变为不可扩展。它返回一个布尔值,表示是否操做成功。

 

观察者模式:使用 Proxy 写一个观察者模式的最简单实现,即实现observableobserve这两个函数。思路observable函数返回一个原始对象的 Proxy 代理,拦截赋值操做,触发充当观察者的各个函数

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;
}

 首先:须要定义observable ,定义代理(添加须要被代理的对象),在执行set(例子中为set 对象的add 添加)操做时,代理对象首先在目标对象(原始对象)设置属性与值,而后循环执行观察者函数(例子中print方法)。

const person = observable({
  name: '张三',
  age: 20
});

function print() {
  console.log(`${person.name}, ${person.age}`)
}

observe(print);
person.name = '李四';
// 输出
// 李四, 20
相关文章
相关标签/搜索