JavaScript响应式原理通过Proxy拦截对象的get和set操作,在get中收集依赖,在set时触发更新。使用reactive将对象代理,watchEffect注册副作用函数自动追踪依赖,数据变化时更新DOM或执行回调,结合WeakMap存储依赖,递归处理嵌套对象,实现简易响应式系统。

JavaScript数据绑定的响应式原理,核心在于监听数据变化,并自动更新相关依赖。实现这一机制的关键是拦截对象属性的读取和修改操作,从而触发视图或其他副作用的更新。现代框架如Vue 3就是基于Proxy实现的响应式系统,下面一步步说明如何手动实现一个简单的响应式数据绑定。
1. 使用Proxy监听数据变化
Proxy可以代理整个对象,拦截其属性的get和set操作,是实现响应式的理想选择。
基本思路:
- 在get中收集依赖(谁在使用这个值)
- 在set中触发更新(通知依赖进行更新)
let activeEffect = null;
function watchEffect(effect) {
activeEffect = effect;
effect(); // 执行一次以触发getter,收集依赖
activeEffect = null;
}
const targetMap = new WeakMap();
function reactive(target) {
return new Proxy(target, {
get(obj, key) {
const dep = getDep(obj, key);
if (activeEffect) {
dep.add(activeEffect); // 收集依赖
}
return Reflect.get(obj, key);
},
set(obj, key, value) {
const result = Reflect.set(obj, key, value);
const dep = getDep(obj, key);
dep.forEach(effect => effect()); // 触发所有依赖
return result;
}
});
}
function getDep(obj, key) {
let depsMap = targetMap.get(obj);
if (!depsMap) {
depsMap = new Map();
targetMap.set(obj, depsMap);
}
let dep = depsMap.get(key);
if (!dep) {
dep = new Set();
depsMap.set(key, dep);
}
return dep;
}
2. 创建响应式对象并绑定更新函数
将普通对象转为响应式,并通过watchEffect注册副作用函数,实现自动更新。
立即学习“Java免费学习笔记(深入)”;
使用示例:
const state = reactive({
count: 0
});
watchEffect(() => {
console.log('Count:', state.count); // 自动追踪count依赖
});
state.count++; // 控制台输出:Count: 1
state.count++; // 控制台输出:Count: 2
3. 模拟视图更新(简单DOM绑定)
将响应式数据绑定到页面元素上,数据变化时自动更新DOM。
专为中小型企业定制的网络办公软件,富有竞争力的十大特性: 1、独创 web服务器、数据库和应用程序全部自动傻瓜安装,建立企业信息中枢 只需3分钟。 2、客户机无需安装专用软件,使用浏览器即可实现全球办公。 3、集成Internet邮件管理组件,提供web方式的远程邮件服务。 4、集成语音会议组件,节省长途话费开支。 5、集成手机短信组件,重要信息可直接发送到员工手机。 6、集成网络硬
例如,绑定一个文本节点:
const view = document.getElementById('app');
watchEffect(() => {
view.textContent = `Count: ${state.count}`;
});
当state.count变化时,页面内容会自动刷新,无需手动调用渲染函数。
4. 处理嵌套对象与数组
Proxy默认只代理一层,深层对象需要递归代理。
改进reactive函数:
function reactive(target) {
if (typeof target !== 'object' || target === null) {
return target;
}
return new Proxy(target, {
get(obj, key) {
const res = Reflect.get(obj, key);
if (typeof res === 'object' && res !== null) {
return reactive(res); // 递归代理
}
const dep = getDep(obj, key);
if (activeEffect) {
dep.add(activeEffect);
}
return res;
},
set(obj, key, value) {
const result = Reflect.set(obj, key, reactive(value));
const dep = getDep(obj, key);
dep.forEach(effect => effect());
return result;
}
});
}
基本上就这些。通过Proxy + 依赖收集 + 副作用执行,就能实现一个简易但完整的响应式系统。实际框架中还会加入调度器、计算属性、清理依赖等优化,但核心逻辑一致。不复杂但容易忽略细节,比如正确处理嵌套和避免重复收集依赖。









