• 13.Reflect


    1.概述

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

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

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

    // 老写法
    try {
      Object.defineProperty(target, property, attributes);
      // success
    } catch (e) {
      // failure
    }
    
    // 新写法
    if (Reflect.defineProperty(target, property, attributes)) {
      // success
    } else {
      // failure
    }

    (3) 让Object操作都变成函数行为。某些Object操作是命令式,比如name in objdelete obj[name],而Reflect.has(obj, name)Reflect.deleteProperty(obj, name)让它们变成了函数行为。

    // 老写法
    'assign' in Object // true
    
    // 新写法
    Reflect.has(Object, 'assign') // true

    (4)Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。

    Proxy(target, {
      set: function(target, name, value, receiver) {
        var success = Reflect.set(target,name, value, receiver);
        if (success) {
          log('property ' + name + ' on ' + target + ' set to ' + value);
        }
        return success;
      }
    });

    上面代码中,Proxy方法拦截target对象的属性赋值行为。它采用Reflect.set方法将值赋值给对象的属性,确保完成原有的行为,然后再部署额外的功能。

    2.静态方法

    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)

    上面这些方法的作用,大部分与Object对象的同名方法的作用都是相同的,而且它与Proxy对象的方法是一一对应的。

    3.实例:使用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 写一个观察者模式的最简单实现,即实现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;
    }

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

  • 相关阅读:
    什么是RESTFUL?REST的请求方法有哪些,有什么区别?
    post提交的数据有哪几种编码格式?能否通过URL参数获取用户账户密码
    什么是jsp?jsp的内置对象有哪些?
    Session和Cookie的区别
    全面系统讲解CSS工作应用+面试一步搞定
    CSS实例:翻转图片、滚动图片栏、打开大门
    【HTML5版】导出Table数据并保存为Excel
    通过HTML5的getUserMedia实现拍照功能
    Day 19: EmberJS 入门指南
    18个基于 HTML5 Canvas 开发的图表库
  • 原文地址:https://www.cnblogs.com/miangao/p/6946437.html
Copyright © 2020-2023  润新知