es6之Proxy实现观察者模式

Proxy介绍

ES6中的Proxy是一种用于创建代理对象的特殊对象。它允许我们定义自定义行为,例如拦截和修改对象的默认操作。Proxy可以用于拦截对象的各种操作,包括属性访问、赋值、函数调用等。

Proxy的作用是在目标对象之前架设一层拦截,可以对目标对象进行各种操作的拦截和自定义处理。通过使用Proxy,我们可以实现对目标对象的访问控制、数据验证、属性劫持等功能。

Proxy通过使用一个代理对象来包装目标对象,并提供了一组钩子函数(也称为“陷阱”),这些钩子函数可以在代理对象上进行操作。当我们对代理对象进行操作时,实际上是在调用这些钩子函数,并根据需要进行相应的处理。

Proxy属性操作介绍

  • get(target, propKey, receiver) :拦截对象属性的读取
  • set(target, propKey, value, receiver) :拦截对象属性的设置返回一个布尔值。
  • has(target, propKey) :拦截propKey in proxy的操作,返回一个布尔值。
  • deleteProperty(target, propKey) :拦截delete proxy[propKey]的操作,返回一个布尔值。
  • ownKeys(target) :拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。
  • getOwnPropertyDescriptor(target, propKey) :拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
  • defineProperty(target, propKey, propDesc) :拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
  • preventExtensions(target) :拦截Object.preventExtensions(proxy),返回一个布尔值。
  • getPrototypeOf(target) :拦截Object.getPrototypeOf(proxy),返回一个对象。
  • isExtensible(target) :拦截Object.isExtensible(proxy),返回一个布尔值。
  • setPrototypeOf(target, proto) :拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
  • apply(target, object, args) :拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。
  • construct(target, args) :拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)。

使用Proxy实现观察者模式

 

观察者模式直观的理解就是因果模式,并且是一因多果。类比数学中的函数,因变量随自变量变化而变化。

观察者模式,侦测被观察者的行为变动。一旦被观察者发生了变化,那么这一行为会被所有观察者所知晓。

观察者模式是一种设计模式,它定义了对象之间的一对多依赖关系,当一个对象(主题)的状态改变时,所有依赖于它的对象(观察者)都会得到通知并自动更新。

在ES6中,Proxy可以用来优雅地实现观察者模式。

创建观察者类

定义一个观察者类,该类包含一个更新方法,用于接收主题发送的通知。

class Observer {
  update(data) {
    console.log('Observer received data:', data);
  }
}
定义处理器对象

创建一个处理器对象,其中的set方法会在目标对象的属性被修改时被调用。在这个方法里,我们可以通知所有注册的观察者。

const handler = {
  set(target, prop, value, receiver) {
    // 使用Reflect来设置值
    const result = Reflect.set(target, prop, value, receiver); 
    if (result) { 
      // 如果设置成功
      console.log(`Property ${prop} set to ${value}`);
      // 通知所有观察者
      target.observers.forEach(observer => observer.update({ prop, value }));
    }
    return result;
  }
};
创建可观察对象

使用Proxy包装目标对象,并传入处理器对象。同时,为目标对象添加一个observers属性来存储观察者列表。

class Observable {
  constructor(data) {
    this.data = data;
    this.proxy = new Proxy(this.data, handler);
    this.observers = [];
  }

  addObserver(observer) {
    this.observers.push(observer);
  }

  removeObserver(observer) {
    this.observers = this.observers.filter(obs => obs !== observer);
  }
}
使用观察者模式

创建观察者实例,然后创建可观察对象,并向其添加观察者。之后,更改可观察对象的属性,观察者将自动收到通知。

const observer = new Observer();
const observableData = new Observable({ job: '前端工程师', age: 30 });

observableData.addObserver(observer);

// 改变可观察对象的属性
observableData.proxy.job = 'java工程师';

相关推荐

  1. Python实现观察模式

    2024-07-10 14:14:06       40 阅读
  2. ES6 Proxy详解

    2024-07-10 14:14:06       39 阅读
  3. 【前端设计模式观察模式

    2024-07-10 14:14:06       44 阅读
  4. 设计模式观察模式

    2024-07-10 14:14:06       40 阅读
  5. 设计模式观察模式

    2024-07-10 14:14:06       42 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-10 14:14:06       4 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-10 14:14:06       5 阅读
  3. 在Django里面运行非项目文件

    2024-07-10 14:14:06       4 阅读
  4. Python语言-面向对象

    2024-07-10 14:14:06       5 阅读

热门阅读

  1. 每天一个数据分析题(四百一十八)- 相关分析

    2024-07-10 14:14:06       9 阅读
  2. 计算机网络面试常见题目(一)

    2024-07-10 14:14:06       12 阅读
  3. vue配置sql规则

    2024-07-10 14:14:06       9 阅读
  4. ios 企业签名证书购买_iOS苹果企业签名须知

    2024-07-10 14:14:06       10 阅读
  5. android 使用系统工具bootchart统计开机时长

    2024-07-10 14:14:06       13 阅读
  6. 【工具分享】FOFA——网络空间测绘搜索引擎

    2024-07-10 14:14:06       9 阅读
  7. 物联网应用,了解一点 WWAN全球网络标准

    2024-07-10 14:14:06       11 阅读
  8. Jupyter Notebook详尽安装教程

    2024-07-10 14:14:06       7 阅读
  9. 实现淘客返利系统中的用户登录与权限管理

    2024-07-10 14:14:06       6 阅读
  10. 【力扣】每日一题—第70题,爬楼梯

    2024-07-10 14:14:06       8 阅读
  11. mysql快速精通(一)DQL数据查询语言

    2024-07-10 14:14:06       10 阅读
  12. 408第二轮复习 数据结构 第七章查找

    2024-07-10 14:14:06       11 阅读