当前位置:首页 > JavaScript

如何js实现watch

2026-02-03 08:22:00JavaScript

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

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

使用Object.defineProperty

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

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可以拦截整个对象的操作,适合深层监听:

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() // 停止监听

自定义发布订阅模式

实现简单的观察者模式:

如何js实现watch

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实现分页

js实现分页

实现分页的基本思路 分页功能通常需要处理数据分割、页码生成和用户交互。核心逻辑包括计算总页数、根据当前页截取数据、渲染页码按钮等。 前端分页实现(静态数据) 假设已有全部数据,仅需前端分页展示:…

js实现vue路由

js实现vue路由

Vue路由基础实现 使用Vue Router实现前端路由需要先安装并配置路由库。Vue Router是Vue.js官方的路由管理器。 安装Vue Router: npm install vue-r…

js实现列表

js实现列表

使用 JavaScript 实现列表 JavaScript 提供了多种方式来实现列表功能,包括数组操作、DOM 元素动态生成等。以下是几种常见的实现方法: 使用数组存储列表数据 数组是 JavaSc…

js分组实现

js分组实现

分组实现方法 在JavaScript中,可以通过多种方式实现数组或对象的分组操作。以下是几种常见的方法: 使用Array.prototype.reduce() 通过reduce方法可以轻松实现数组分…

js实现选题

js实现选题

实现选题功能的JavaScript方法 基础实现方案 使用数组存储选项,通过随机索引选取: const options = ['选项A', '选项B', '选项C', '选项D']; const r…

js怎么实现异步

js怎么实现异步

异步实现方法 JavaScript中实现异步操作主要通过以下几种方式: Promise Promise是ES6引入的异步解决方案,用于处理异步操作的成功或失败状态。 const promise =…