当前位置:首页 > JavaScript

js实现watch

2026-03-14 03:17:00JavaScript

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

使用Proxy实现监听

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

js实现watch

function watch(obj, callback) {
  return new Proxy(obj, {
    set(target, key, value) {
      const oldValue = target[key];
      target[key] = value;
      callback(key, oldValue, value);
      return true;
    }
  });
}

const obj = watch({ count: 0 }, (key, oldValue, newValue) => {
  console.log(`${key} changed from ${oldValue} to ${newValue}`);
});
obj.count = 1; // 输出: count changed from 0 to 1

使用Object.defineProperty实现

适用于较老环境或需要精确控制的情况:

js实现watch

function watch(obj, prop, callback) {
  let value = obj[prop];
  Object.defineProperty(obj, prop, {
    get() { return value; },
    set(newValue) {
      const oldValue = value;
      value = newValue;
      callback(oldValue, newValue);
    }
  });
}

const obj = { count: 0 };
watch(obj, 'count', (oldValue, newValue) => {
  console.log(`count changed from ${oldValue} to ${newValue}`);
});
obj.count = 1; // 输出: count changed from 0 to 1

使用ES6的Reflect和Proxy实现深度监听

对于嵌套对象的深度监听:

function deepWatch(obj, callback) {
  const handler = {
    get(target, key) {
      const value = Reflect.get(target, key);
      if (typeof value === 'object' && value !== null) {
        return new Proxy(value, handler);
      }
      return value;
    },
    set(target, key, value) {
      const oldValue = Reflect.get(target, key);
      const result = Reflect.set(target, key, value);
      callback(key, oldValue, value);
      return result;
    }
  };
  return new Proxy(obj, handler);
}

const obj = deepWatch({ nested: { count: 0 } }, (key, oldValue, newValue) => {
  console.log(`${key} changed from ${oldValue} to ${newValue}`);
});
obj.nested.count = 1; // 输出: count changed from 0 to 1

使用第三方库

现有库如MobX、Vue本身或独立的watch实现:

// 使用MobX示例
import { observable, autorun } from 'mobx';

const obj = observable({ count: 0 });
autorun(() => {
  console.log(`count changed to ${obj.count}`);
});
obj.count = 1; // 自动触发日志输出

注意事项

Proxy无法监听数组的索引变化,需要额外处理数组方法 Object.defineProperty无法监听新增属性,需要预先定义 深度监听可能影响性能,应根据需求权衡

标签: jswatch
分享给朋友:

相关文章

js实现复制到剪贴板

js实现复制到剪贴板

使用document.execCommand方法(传统方式,已废弃但部分浏览器仍支持) 该方法适用于旧版浏览器,但已被标记为废弃。执行前需确保文本已被选中: function copyToClipb…

js 实现分页

js 实现分页

实现分页的基本逻辑 分页功能通常需要后端返回数据总量或总页数,前端根据当前页码和每页条数截取对应数据。以下是一个基于JavaScript的简单分页实现方案: 前端分页实现 假设已有从后端获取的完整数…

js实现延迟

js实现延迟

实现延迟的方法 在JavaScript中,实现延迟操作有多种方式,以下是几种常见的方法: 使用setTimeout函数 setTimeout是JavaScript中最常用的延迟执行方法。它接受一个回…

js实现目录

js实现目录

实现目录的基本思路 在JavaScript中实现目录功能通常涉及以下几个核心步骤:解析文档中的标题元素(如h1-h6),动态生成目录结构,并添加交互逻辑(如点击跳转)。以下是具体实现方法: 解析标题…

js实现vue路由

js实现vue路由

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

js实现代码雨

js实现代码雨

实现代码雨效果 使用HTML5 Canvas和JavaScript可以轻松实现经典的代码雨效果。以下是完整的实现代码和说明: HTML结构 <!DOCTYPE html> <…