js实现watch
在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实现:
// 使用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无法监听新增属性,需要预先定义 深度监听可能影响性能,应根据需求权衡






