当前位置:首页 > JavaScript

js watch 实现

2026-04-05 23:09:05JavaScript

js watch 实现

js watch 实现

实现 JavaScript 的 watch 功能

在 JavaScript 中实现类似 Vue 的 watch 功能,可以通过以下几种方式:

使用 Proxy 实现数据监听

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

const data = { count: 0 };
const watchedData = createWatcher(data, (key, oldValue, newValue) => {
  console.log(`属性 ${key} 从 ${oldValue} 变为 ${newValue}`);
});

watchedData.count = 1; // 输出: 属性 count 从 0 变为 1

使用 Object.defineProperty 实现

function defineReactive(obj, key, val, callback) {
  Object.defineProperty(obj, key, {
    get() {
      return val;
    },
    set(newVal) {
      const oldVal = val;
      val = newVal;
      callback(key, oldVal, newVal);
    }
  });
}

const data = {};
defineReactive(data, 'message', 'hello', (key, oldVal, newVal) => {
  console.log(`${key} changed from ${oldVal} to ${newVal}`);
});

data.message = 'world'; // 输出: message changed from hello to world

使用 ES6 的 Reflect 和 Proxy

class Watcher {
  constructor(data, callback) {
    this.data = data;
    this.callback = callback;
    return this.proxy();
  }

  proxy() {
    return new Proxy(this.data, {
      set: (target, key, value) => {
        const oldValue = target[key];
        Reflect.set(target, key, value);
        this.callback(key, oldValue, value);
        return true;
      }
    });
  }
}

const obj = { name: 'Alice' };
const watchedObj = new Watcher(obj, (key, oldVal, newVal) => {
  console.log(`属性 ${key} 变化: ${oldVal} -> ${newVal}`);
});

watchedObj.name = 'Bob'; // 输出: 属性 name 变化: Alice -> Bob

实现深度监听

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

const nestedObj = { user: { name: 'John' } };
const watchedNested = deepWatch(nestedObj, (path, oldVal, newVal) => {
  console.log(`${path} changed from ${oldVal} to ${newVal}`);
});

watchedNested.user.name = 'Doe'; // 输出: user.name changed from John to Doe

注意事项

  • Proxy 无法监听数组的某些方法(如 push/pop),需要额外处理
  • Object.defineProperty 对数组支持有限,且无法监听新增属性
  • 深度监听可能影响性能,应根据实际需求决定监听层级
  • 现代前端框架(如 Vue 3)已使用 Proxy 替代 Object.defineProperty

以上方法可以根据具体需求选择使用,Proxy 方案更现代且功能更强大,但需要考虑浏览器兼容性。

标签: jswatch
分享给朋友:

相关文章

js实现论坛

js实现论坛

实现论坛的基本功能 使用JavaScript实现一个论坛需要结合前端和后端技术。前端可以使用React、Vue或Angular等框架,后端可以选择Node.js配合Express或Koa框架。数据库可…

js实现百叶窗

js实现百叶窗

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

js类实现

js类实现

使用类实现 JavaScript 功能 在 JavaScript 中,类(Class)是一种语法糖,基于原型继承机制。通过 class 关键字可以更直观地定义对象模板。 基本类定义 class…

js实现密码

js实现密码

密码强度验证 使用正则表达式验证密码强度是一种常见方法。以下代码检查密码是否包含大小写字母、数字和特殊字符,且长度至少为8位: function checkPasswordStrength(pass…

js验证码的实现

js验证码的实现

验证码的基本实现原理 验证码(CAPTCHA)的核心目标是区分人类用户和自动化程序。JavaScript可用于生成或验证客户端验证码,但需注意纯前端验证可能被绕过,通常需结合后端验证。 纯前端验证码…

js 实现日历

js 实现日历

实现日历的基本思路 日历的核心功能是展示日期,并允许用户进行日期选择或导航。JavaScript 可以动态生成日历的 HTML 结构,并处理用户交互逻辑。 基础日历结构 日历通常包含头部(显示月份和…