当前位置:首页 > JavaScript

js实现watch

2026-04-05 21:23:35JavaScript

在JavaScript中实现类似Vue的watch功能

实现一个简单的数据监听器,当数据变化时触发回调函数。以下是几种常见方法:

js实现watch

使用Proxy实现数据监听

function watch(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 = watch(data, (key, oldVal, newVal) => {
  console.log(`${key} changed from ${oldVal} to ${newVal}`);
});

watchedData.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(newVal) {
      const oldVal = value;
      value = newVal;
      callback(oldVal, newVal);
    }
  });
}

// 使用示例
const data = { count: 0 };
watch(data, 'count', (oldVal, newVal) => {
  console.log(`count changed from ${oldVal} to ${newVal}`);
});

data.count = 1; // 输出: count changed from 0 to 1

深度监听对象变化

function deepWatch(target, callback) {
  return new Proxy(target, {
    get(obj, prop) {
      const value = obj[prop];
      if (typeof value === 'object' && value !== null) {
        return deepWatch(value, callback);
      }
      return value;
    },
    set(obj, prop, value) {
      const oldValue = obj[prop];
      obj[prop] = value;
      callback(prop, oldValue, value);
      return true;
    }
  });
}

// 使用示例
const data = { user: { name: 'Alice' } };
const watchedData = deepWatch(data, (key, oldVal, newVal) => {
  console.log(`${key} changed from ${oldVal} to ${newVal}`);
});

watchedData.user.name = 'Bob'; // 输出: name changed from Alice to Bob

实现多属性监听

function createWatcher(target) {
  const callbacks = {};

  const proxy = new Proxy(target, {
    set(obj, prop, value) {
      const oldValue = obj[prop];
      obj[prop] = value;
      if (callbacks[prop]) {
        callbacks[prop].forEach(cb => cb(oldValue, value));
      }
      return true;
    }
  });

  return {
    data: proxy,
    watch(prop, callback) {
      if (!callbacks[prop]) callbacks[prop] = [];
      callbacks[prop].push(callback);
    }
  };
}

// 使用示例
const { data, watch } = createWatcher({ count: 0, name: '' });
watch('count', (oldVal, newVal) => {
  console.log(`Count changed: ${oldVal} → ${newVal}`);
});
watch('name', (oldVal, newVal) => {
  console.log(`Name changed: ${oldVal} → ${newVal}`);
});

data.count = 1; // 输出: Count changed: 0 → 1
data.name = 'Alice'; // 输出: Name changed:  → Alice

这些方法展示了JavaScript中实现数据监听的不同方式,可以根据具体需求选择适合的方案。Proxy方案更现代且功能更强大,而Object.defineProperty方案则兼容性更好。

标签: jswatch
分享给朋友:

相关文章

js实现图片放大缩小

js实现图片放大缩小

实现图片放大缩小的基础方法 使用CSS的transform: scale()属性可以快速实现图片的放大缩小效果。通过JavaScript动态修改该属性值: const img = document.…

js实现验证

js实现验证

验证表单输入 使用JavaScript验证表单输入是常见的需求。可以通过监听表单提交事件,检查输入字段是否符合要求。 document.getElementById('myForm').addEve…

js实现拷贝

js实现拷贝

实现文本拷贝 使用 document.execCommand 方法(已废弃但兼容性较好): function copyText(text) { const textarea = document…

js实现论坛

js实现论坛

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

js实现祖玛

js实现祖玛

实现祖玛游戏的核心思路 祖玛游戏的核心玩法是发射彩色珠子,形成三个或以上相同颜色的珠子即可消除。以下是使用JavaScript实现的基本框架。 游戏初始化 创建画布并初始化游戏状态: const…

js实现上传图片

js实现上传图片

使用HTML5的File API实现图片上传 HTML5的File API允许通过JavaScript访问用户选择的文件。需要创建一个文件输入元素,并监听其change事件。 <input t…