当前位置:首页 > JavaScript

如何js实现watch

2026-02-03 08:22:00JavaScript

实现数据监听(Watch)的方法

在JavaScript中实现类似Vue的watch功能,可以通过以下几种方式监听对象属性的变化:

使用Object.defineProperty

通过定义属性的getter/setter实现基础监听:

如何js实现watch

function observe(obj, key, callback) {
  let value = obj[key]
  Object.defineProperty(obj, key, {
    get() {
      return value
    },
    set(newVal) {
      if (newVal !== value) {
        const oldVal = value
        value = newVal
        callback(newVal, oldVal)
      }
    }
  })
}

const data = { count: 0 }
observe(data, 'count', (newVal, oldVal) => {
  console.log(`count changed from ${oldVal} to ${newVal}`)
})

使用Proxy实现深度监听

Proxy可以拦截整个对象的操作,适合深层监听:

如何js实现watch

function createWatcher(target, callback) {
  return new Proxy(target, {
    set(target, key, value, receiver) {
      const oldValue = target[key]
      if (oldValue !== value) {
        Reflect.set(target, key, value, receiver)
        callback(key, value, oldValue)
      }
      return true
    }
  })
}

const store = createWatcher({ price: 10 }, (key, newVal, oldVal) => {
  console.log(`${key} updated: ${oldVal} -> ${newVal}`)
})

第三方库实现

使用现成的观察者模式库更高效:

// 使用MobX
import { observable, observe } from 'mobx'

const obj = observable({ value: 1 })
const disposer = observe(obj, change => {
  console.log(`${change.name} changed`, change)
})

obj.value = 2
disposer() // 停止监听

自定义发布订阅模式

实现简单的观察者模式:

class Watcher {
  constructor() {
    this.subscribers = new Map()
  }

  watch(target, key, callback) {
    if (!this.subscribers.has(target)) {
      this.subscribers.set(target, new Map())
    }
    this.subscribers.get(target).set(key, callback)
  }

  notify(target, key, newVal, oldVal) {
    const callbacks = this.subscribers.get(target)?.get(key)
    callbacks?.(newVal, oldVal)
  }
}

const watcher = new Watcher()
const obj = { data: '' }
watcher.watch(obj, 'data', (newVal) => console.log('Data changed:', newVal))

注意事项

  • 原始方法无法检测数组变化,需特殊处理数组方法
  • Proxy有更好的性能但存在浏览器兼容性问题
  • 深层嵌套对象需要递归处理
  • 考虑使用WeakMap避免内存泄漏

标签: jswatch
分享给朋友:

相关文章

js实现vue

js实现vue

Vue.js 简介 Vue.js 是一个渐进式 JavaScript 框架,用于构建用户界面。其核心库专注于视图层,易于与其他库或现有项目整合。 实现 Vue.js 的基本步骤 安装 Vue.…

js实现

js实现

实现 JavaScript 功能的方法 在 JavaScript 中实现特定功能通常涉及多个步骤。以下是常见的实现方法: 基础语法和变量声明 使用 let 或 const 声明变量: let co…

js实现轮播图

js实现轮播图

基础轮播图实现 使用HTML、CSS和JavaScript实现一个简单的自动轮播图。HTML结构包含一个容器和多个图片项。 <div class="slider"> <div…

js 实现继承

js 实现继承

原型链继承 通过让子类的原型对象指向父类的实例来实现继承。子类实例可以访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Pa…

js 进度条的实现

js 进度条的实现

使用 HTML 和 CSS 创建基础进度条 HTML 结构可以简单使用一个 div 元素作为容器,内部嵌套另一个 div 表示进度: <div class="progress-contain…

js实现选项卡

js实现选项卡

实现选项卡的基本思路 选项卡通常由一组标签和对应的内容面板组成。点击标签时,显示对应的内容面板,隐藏其他面板。实现这一效果需要结合HTML结构、CSS样式和JavaScript交互逻辑。 HTML结…