js实现watch功能
使用 Object.defineProperty 实现基本监听
通过 Object.defineProperty 可以监听对象属性的变化。定义一个 watch 函数,当目标属性发生变化时触发回调。
function watch(obj, prop, callback) {
let value = obj[prop];
Object.defineProperty(obj, prop, {
get() {
return value;
},
set(newValue) {
if (newValue !== value) {
const oldValue = value;
value = newValue;
callback(newValue, oldValue);
}
},
});
}
// 示例
const user = { name: 'Alice' };
watch(user, 'name', (newVal, oldVal) => {
console.log(`Name changed from ${oldVal} to ${newVal}`);
});
user.name = 'Bob'; // 输出: Name changed from Alice to Bob
使用 Proxy 实现深度监听
Proxy 可以拦截对象的多种操作,适合监听嵌套对象或数组的变化。

function deepWatch(obj, callback) {
return new Proxy(obj, {
set(target, prop, value) {
const oldValue = target[prop];
target[prop] = value;
callback(prop, oldValue, value);
return true;
},
get(target, prop) {
const value = target[prop];
return typeof value === 'object' && value !== null
? deepWatch(value, callback)
: value;
},
});
}
// 示例
const state = deepWatch({ user: { name: 'Alice' } }, (prop, oldVal, newVal) => {
console.log(`Property ${prop} changed from ${oldVal} to ${newVal}`);
});
state.user.name = 'Bob'; // 输出: Property name changed from Alice to Bob
监听数组变化
通过重写数组原型方法实现对数组操作的监听。

function watchArray(arr, callback) {
const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);
const methods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];
methods.forEach(method => {
arrayMethods[method] = function(...args) {
const result = arrayProto[method].apply(this, args);
callback(method, args, this);
return result;
};
});
arr.__proto__ = arrayMethods;
return arr;
}
// 示例
const list = watchArray([1, 2], (method, args, arr) => {
console.log(`Array ${method} called with args: ${args}`);
});
list.push(3); // 输出: Array push called with args: 3
结合 Proxy 和 Reflect 实现响应式系统
通过 Proxy 和 Reflect 构建更完善的响应式系统,支持依赖收集和触发更新。
const reactiveMap = new WeakMap();
let activeEffect = null;
function track(target, prop) {
if (activeEffect) {
let depsMap = reactiveMap.get(target);
if (!depsMap) {
depsMap = new Map();
reactiveMap.set(target, depsMap);
}
let dep = depsMap.get(prop);
if (!dep) {
dep = new Set();
depsMap.set(prop, dep);
}
dep.add(activeEffect);
}
}
function trigger(target, prop) {
const depsMap = reactiveMap.get(target);
if (depsMap && depsMap.has(prop)) {
depsMap.get(prop).forEach(effect => effect());
}
}
function reactive(obj) {
return new Proxy(obj, {
get(target, prop) {
track(target, prop);
return Reflect.get(target, prop);
},
set(target, prop, value) {
Reflect.set(target, prop, value);
trigger(target, prop);
return true;
},
});
}
function effect(fn) {
activeEffect = fn;
fn();
activeEffect = null;
}
// 示例
const state = reactive({ count: 0 });
effect(() => {
console.log(`Count is: ${state.count}`);
});
state.count++; // 输出: Count is: 1
使用第三方库实现监听
若需要更成熟的解决方案,可直接使用 Vue3 的 reactive 或 MobX 等库。
// 使用 Vue3 的 reactive
import { reactive, watchEffect } from 'vue';
const state = reactive({ count: 0 });
watchEffect(() => {
console.log(`Count is: ${state.count}`);
});
state.count++; // 输出: Count is: 1
// 使用 MobX
import { observable, autorun } from 'mobx';
const store = observable({ count: 0 });
autorun(() => {
console.log(`Count is: ${store.count}`);
});
store.count++; // 输出: Count is: 1






