当前位置:首页 > JavaScript

js实现obs

2026-03-15 09:06:48JavaScript

JavaScript 实现 OBS(观察者模式)

观察者模式(Observer Pattern)是一种设计模式,允许对象(观察者)订阅另一个对象(被观察者)的状态变化。当被观察者的状态发生变化时,会自动通知所有观察者。

js实现obs

基本实现

class Subject {
  constructor() {
    this.observers = [];
  }

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

  unsubscribe(observer) {
    this.observers = this.observers.filter(obs => obs !== observer);
  }

  notify(data) {
    this.observers.forEach(observer => observer.update(data));
  }
}

class Observer {
  update(data) {
    console.log('Observer received:', data);
  }
}

// 使用示例
const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();

subject.subscribe(observer1);
subject.subscribe(observer2);

subject.notify('Hello Observers!');

更实用的实现

class Observable {
  constructor() {
    this.subscribers = new Set();
  }

  subscribe(callback) {
    this.subscribers.add(callback);
    return () => this.unsubscribe(callback);
  }

  unsubscribe(callback) {
    this.subscribers.delete(callback);
  }

  notify(data) {
    this.subscribers.forEach(callback => callback(data));
  }
}

// 使用示例
const observable = new Observable();

const unsubscribe1 = observable.subscribe(data => {
  console.log('Subscriber 1:', data);
});

const unsubscribe2 = observable.subscribe(data => {
  console.log('Subscriber 2:', data);
});

observable.notify('First notification');

unsubscribe1();

observable.notify('Second notification');

支持多种事件类型

class EventEmitter {
  constructor() {
    this.events = {};
  }

  on(eventName, callback) {
    if (!this.events[eventName]) {
      this.events[eventName] = new Set();
    }
    this.events[eventName].add(callback);
    return () => this.off(eventName, callback);
  }

  off(eventName, callback) {
    if (this.events[eventName]) {
      this.events[eventName].delete(callback);
    }
  }

  emit(eventName, data) {
    if (this.events[eventName]) {
      this.events[eventName].forEach(callback => callback(data));
    }
  }
}

// 使用示例
const emitter = new EventEmitter();

const unsubscribeClick = emitter.on('click', data => {
  console.log('Click event:', data);
});

emitter.on('hover', data => {
  console.log('Hover event:', data);
});

emitter.emit('click', { x: 100, y: 200 });
emitter.emit('hover', { element: 'button' });

unsubscribeClick();

emitter.emit('click', 'This wont be logged');

响应式属性实现

function createReactiveObject(obj) {
  const subscribers = new Map();

  return new Proxy(obj, {
    set(target, property, value) {
      target[property] = value;
      if (subscribers.has(property)) {
        subscribers.get(property).forEach(callback => callback(value));
      }
      return true;
    },
    get(target, property) {
      if (typeof target[property] === 'object' && target[property] !== null) {
        return createReactiveObject(target[property]);
      }
      return target[property];
    }
  });
}

function watchProperty(obj, property, callback) {
  if (!obj._subscribers) {
    obj._subscribers = new Map();
  }
  if (!obj._subscribers.has(property)) {
    obj._subscribers.set(property, new Set());
  }
  obj._subscribers.get(property).add(callback);
  return () => obj._subscribers.get(property).delete(callback);
}

// 使用示例
const state = createReactiveObject({
  user: {
    name: 'John',
    age: 30
  },
  loggedIn: false
});

watchProperty(state.user, 'name', (newName) => {
  console.log('Name changed to:', newName);
});

watchProperty(state, 'loggedIn', (isLoggedIn) => {
  console.log('Login status changed:', isLoggedIn);
});

state.user.name = 'Jane';
state.loggedIn = true;

这些实现展示了JavaScript中观察者模式的不同应用场景,从基础实现到更复杂的响应式系统。根据具体需求可以选择合适的实现方式。

标签: jsobs
分享给朋友:

相关文章

vue实现js休眠

vue实现js休眠

Vue 中实现 JavaScript 休眠 在 Vue 中实现 JavaScript 休眠通常需要使用异步方式,以避免阻塞主线程。以下是几种常见方法: 使用 setTimeout 和 Pro…

js 实现倒计时

js 实现倒计时

实现倒计时的基本方法 使用 JavaScript 实现倒计时可以通过 setInterval 或 setTimeout 结合日期计算来完成。以下是两种常见实现方式。 使用 setInterval 实…

js实现游标

js实现游标

使用JavaScript实现游标 在JavaScript中,可以通过操作DOM元素的cursor样式属性来实现自定义游标效果。以下是几种常见的实现方法: 修改默认鼠标指针样式 通过CSS的curso…

js实现投球

js实现投球

实现投球动画的基本思路 使用JavaScript和CSS动画结合的方式模拟投球效果。核心是通过改变元素的位置、旋转和缩放属性,配合定时器或CSS过渡实现平滑动画。 创建基础HTML结构 <di…

js实现vue路由

js实现vue路由

Vue 路由的基本实现 在 Vue.js 中实现路由功能通常使用 Vue Router 库。Vue Router 是 Vue.js 官方的路由管理器,用于构建单页面应用(SPA)。 安装 Vue R…

js实现文字滚动

js实现文字滚动

实现文字滚动的几种方法 使用CSS动画实现滚动 通过CSS的@keyframes和transform属性可以实现平滑的文字滚动效果。 <style> .scroll-text { w…