ES6 (十四)Reflect


简介

  • Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。Reflect对象的设计目的有这样几个。

    • 将 Object 对象的 一些明显属于语言内部的方法 (比如 Object.defineProperty),放到 Reflect 对象上。现阶段,某些方法 同时在 Object 和 Reflect 对象上部署,未来的新方法将只部署在 Reflect 对象上。意思是可以从 Reflect 对象上 拿到语言内部的方法

    • 修改 那些方法 的返回结果,使其更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。从而避免了 try catch 的繁琐写法

      // 老写法
      try {
        Object.defineProperty(target, property, attributes);
        // success
      } catch (e) {
        // failure
      }
      
      // 新写法
      if (Reflect.defineProperty(target, property, attributes)) {
        // success
      } else {
        // failure
      }
      
    • 让 Object 操作变成函数行为。某些 Object 操作是命令式。比如name in objdelete obj[name],而Reflect.has(obj, name)Reflect.deleteProperty(obj, name)让它们变成了函数行为。

      // 老写法
      'assign' in Object // true
      
      // 新写法
      Reflect.has(Object, 'assign') // true
      
    • Reflect 对象的方法 与 Proxy 对象的方法 一 一 对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。为 Proxy 设计来的

    有了Reflect对象以后,很多操作会更易读。

    // 老写法
    Function.prototype.apply.call(Math.floor, undefined, [1.75]) // 1
    
    // 新写法
    Reflect.apply(Math.floor, undefined, [1.75]) // 1
    

静态方法

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的方法类似。


观察者模式

观察者模式(Observer mode)指的是函数自动观察数据对象,一旦对象有变化,函数就会自动执行。

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

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

observe(print);
person.name = '李四';
// 输出
// 李四, 20
// 上面代码中,数据对象person是观察目标,函数print是观察者。一旦数据对象发生变化,print就会自动执行。

用 Proxy 和 Reflect 实现观察者模式

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

上面代码中,先定义了一个Set集合,所有观察者函数都放进这个集合。然后,observable函数返回原始对象的代理,拦截赋值操作。拦截函数set之中,会自动执行所有观察者。


总结

本文主要介绍了 ES6 新增的 Reflect 的用法, Reflect 主要就是 Object 的一个映射Reflect 有 Object 上一些属于语言内部的方法,后面添加的方法也会慢慢往 Reflect 上面迁移。主要作用就是配合 Proxy 来更优雅地完成代理拦截功能,实现 JS 的元编程能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值