js实现watch
在JavaScript中实现类似Vue的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方案则兼容性更好。






