当前位置:首页 > JavaScript

js实现watch

2026-03-14 03:17:00JavaScript

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

使用Proxy实现监听

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

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

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

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实现:

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

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

js 实现链表

js 实现链表

链表的基本概念 链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。与数组不同,链表在内存中是非连续存储的,插入和删除操作效率较高。 链表的实现 在 JavaScrip…

js实现百叶窗

js实现百叶窗

使用CSS和JavaScript实现百叶窗效果 通过CSS动画和JavaScript事件监听可以实现百叶窗效果。核心思路是将内容区域分割为多个条状元素,通过控制它们的展开/折叠状态来模拟百叶窗。 &…

js实现跑马灯

js实现跑马灯

实现跑马灯效果 使用HTML和JavaScript可以轻松实现跑马灯效果。以下是两种常见的实现方式: HTML结构 <div id="marquee"> <span>…

js实现路由

js实现路由

js实现路由的方法 在JavaScript中实现路由功能可以通过多种方式完成,以下是几种常见的方法: 使用原生JavaScript实现路由 通过监听window.onhashchange事件来实现基…

js实现搜索

js实现搜索

实现搜索功能的方法 在JavaScript中实现搜索功能可以通过多种方式完成,以下是几种常见的实现方法。 使用数组的filter方法 通过数组的filter方法可以筛选出符合条件的数据项。假设有一个…