javascript如何实现双向数据绑定_有哪些核心思路?
发布时间 - 2026-01-05 00:00:00 点击率:次Vue 2 用 Object.defineProperty 实现响应式,但无法监听新增/删除属性和数组索引赋值;Proxy 可全面拦截且支持懒代理,但不兼容 IE;v-model 是语法糖,依赖底层响应式系统;脏检查和发布-订阅是兼容性好但有性能或内存泄漏风险的替代方案。
Object.defineProperty 是最直接的劫持方式
在 Vue 2 中,Object.defineProperty 是实现响应式的核心。它能监听对象属性的 get 和 set,从而在读取时收集依赖、赋值时触发更新。
关键限制在于:它无法监听新增/删除属性,也不
能直接代理数组索引赋值(如 arr[0] = 1),所以 Vue 2 对数组方法做了重写,对对象则要求用 Vue.set。
- 必须遍历对象所有已有属性调用
Object.defineProperty,否则后续添加的属性不响应 - 嵌套对象需递归处理,否则深层属性修改不会触发视图更新
- 不能代理 Map、Set、class 实例等非普通对象
function observe(obj) {
if (typeof obj !== 'object' || obj === null) return;
Object.keys(obj).forEach(key => {
let internalValue = obj[key];
observe(internalValue); // 递归
Object.defineProperty(obj, key, {
get() { console.log('get', key); return internalValue; },
set(newVal) {
console.log('set', key, newVal);
internalValue = newVal;
// 这里应通知 watcher 更新
}
});
});
}
Proxy 可以替代 defineProperty 实现更完整的拦截
Proxy 是 ES6 提供的原生代理机制,能拦截对象的任意操作:读取、赋值、in、delete、has、iterate,甚至数组索引和长度变更。
相比 Object.defineProperty,它天然支持动态增删属性、数组下标赋值、Map/Set,且无需递归初始化——可以懒代理(访问时再代理子属性)。
- 一个
Proxy实例只能代理一层,仍需在get中对返回值做代理(即“懒代理”) - 不能直接代理普通函数或原始值,需包装成对象
- IE 完全不支持,若需兼容低版本浏览器,不能单独使用
function reactive(obj) {
if (typeof obj !== 'object' || obj === null) return obj;
return new Proxy(obj, {
get(target, key, receiver) {
const res = Reflect.get(target, key, receiver);
// 这里可做依赖收集
return typeof res === 'object' && res !== null ? reactive(res) : res;
},
set(target, key, newVal, receiver) {
const oldVal = target[key];
const res = Reflect.set(target, key, newVal, receiver);
// 这里可触发更新
return res;
}
});
}
v-model 的本质是语法糖,不是双向绑定的实现机制
v-model 在 Vue 中只是对 :value + @input(或特定事件)的封装;React 的 value + onChange 组合也同理。它们本身不提供响应式能力,只是约定好的“受控组件”写法。
真正让数据变化驱动 UI、UI 输入又反向更新数据的,是底层响应式系统(defineProperty 或 Proxy)+ 视图更新调度(如 queueFlush)共同完成的。
-
v-model在不同元素上会解析为不同事件:input、change、update:modelValue - 自定义组件要支持
v-model,需显式声明modelValueprop 并触发update:modelValue事件 - 没有响应式系统支撑,
v-model只是单向绑定的简写,无法自动同步
脏检查和发布-订阅是绕过语言限制的替代思路
AngularJS 用的是脏检查($digest 循环),通过定时比对新旧值来判断是否更新;而 RxJS 或手写 EventEmitter 则属于典型的发布-订阅模式:数据变更时主动 emit,视图 subscribe 后响应。
这两种方式不依赖语言特性,因此兼容性极好,但代价明显:脏检查有性能开销,尤其在大量 watcher 场景;发布-订阅需要手动调用 emit,容易遗漏或重复触发。
- 脏检查无法感知异步任务外的变更(比如
setTimeout外部改值),需手动$apply - 发布-订阅中,如果忘记取消订阅(
unsubscribe),容易造成内存泄漏 - 两者都无法自动追踪嵌套属性路径(如
a.b.c),需靠路径字符串或 proxy 包装兜底
Proxy 是当前最平衡的选择,但要注意它的代理不可逆、无法被 JSON.stringify 正常序列化,且调试时控制台显示为 Proxy 对象而非原始结构——这些细节往往在联调或 SSR 场景中才突然暴露。
# vue
# react
# javascript
# es6
# java
# js
# json
# 浏览器
# app
# proxy
# 异步任务
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
js实现点击每个li节点,都弹出其文本值及修改
Laravel如何实现全文搜索功能?(Scout和Algolia示例)
googleplay官方入口在哪里_Google Play官方商店快速入口指南
网站建设要注意的标准 促进网站用户好感度!
厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?
Laravel如何自定义错误页面(404, 500)?(代码示例)
深圳防火门网站制作公司,深圳中天明防火门怎么编码?
Linux系统命令中tree命令详解
Python图片处理进阶教程_Pillow滤镜与图像增强
香港服务器建站指南:免备案优势与SEO优化技巧全解析
油猴 教程,油猴搜脚本为什么会网页无法显示?
百度输入法全感官ai怎么关 百度输入法全感官皮肤关闭
西安专业网站制作公司有哪些,陕西省建行官方网站?
Laravel如何从数据库删除数据_Laravel destroy和delete方法区别
如何在万网自助建站平台快速创建网站?
浅谈Javascript中的Label语句
微信公众帐号开发教程之图文消息全攻略
Laravel怎么自定义错误页面_Laravel修改404和500页面模板
Laravel怎么定时执行任务_Laravel任务调度器Schedule配置与Cron设置【教程】
Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载
Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】
Laravel的.env文件有什么用_Laravel环境变量配置与管理详解
Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】
Laravel如何生成和使用数据填充?(Seeder和Factory示例)
潮流网站制作头像软件下载,适合母子的网名有哪些?
网站制作免费,什么网站能看正片电影?
如何获取免费开源的自助建站系统源码?
Laravel怎么使用Session存储数据_Laravel会话管理与自定义驱动配置【详解】
Laravel怎么连接多个数据库_Laravel多数据库连接配置
如何在新浪SAE免费搭建个人博客?
如何用西部建站助手快速创建专业网站?
Claude怎样写结构化提示词_Claude结构化提示词写法【教程】
如何制作一个表白网站视频,关于勇敢表白的小标题?
网站制作价目表怎么做,珍爱网婚介费用多少?
如何在建站主机中优化服务器配置?
php增删改查怎么学_零基础入门php数据库操作必知基础【教程】
Win11怎么设置默认图片查看器_Windows11照片应用关联设置
Swift中循环语句中的转移语句 break 和 continue
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
Laravel怎么解决跨域问题_Laravel配置CORS跨域访问
香港服务器建站指南:外贸独立站搭建与跨境电商配置流程
Laravel队列任务超时怎么办_Laravel Queue Timeout设置详解
详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)
Laravel的Blade指令怎么自定义_创建你自己的Laravel Blade Directives
如何打造高效商业网站?建站目的决定转化率
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
html5怎么画眼睛_HT5用Canvas或SVG画眼球瞳孔加JS控制动态【绘制】
如何在阿里云服务器自主搭建网站?
Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制
ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法

