vue2数据响应式

这是一个简单的 JavaScript 数据响应式 实现示例,使用了 Object.defineProperty 来拦截属性的读取和设置操作。下面是对代码的逐行解析:


代码分析

javascript 复制代码
function observe(obj) {
    for (const key in obj) {
        let internalValue = obj[key];
        Object.defineProperty(obj, key, {
            get: function () {
                // 记录:是哪个函数在用我
                return internalValue;
            },
            set: function (val) {
                internalValue = val;
                // 运行:执行用我的函数
            },
        });
    }
}

1. 函数目的

  • 将传入的对象 obj 转换为响应式对象:当属性被读取或修改时,可以执行额外操作(如依赖收集、触发更新)。

2. 遍历对象属性

javascript 复制代码
for (const key in obj) {
  • 遍历 obj 的所有可枚举属性。

3. 闭包保存属性值

javascript 复制代码
let internalValue = obj[key];
  • 用局部变量 internalValue 保存属性当前值,避免在 getter/setter 中直接使用 obj[key] 导致递归调用。

4. 使用 Object.defineProperty 重定义属性

javascript 复制代码
Object.defineProperty(obj, key, { ... });
  • 将每个属性转为 getter/setter,实现拦截。

5. Getter

javascript 复制代码
get: function () {
    // 记录:是哪个函数在用我
    return internalValue;
}
  • 当属性被读取时,返回 internalValue
  • 注释提示这里可以用于依赖收集(例如 Vue 2 中记录当前正在执行的渲染函数或计算属性)。

6. Setter

javascript 复制代码
set: function (val) {
    internalValue = val;
    // 运行:执行用我的函数
}
  • 当属性被修改时,更新 internalValue
  • 注释提示这里可以用于触发更新(例如通知所有依赖该属性的函数重新执行)。

存在的问题

  1. 只能拦截已有属性 :如果后续给对象新增属性,不会被响应式处理(Vue 2 中需用 Vue.set)。
  2. 数组变异方法不支持 :如 pushpop 等不会触发 setter(Vue 2 中通过重写数组方法解决)。
  3. 性能问题:遍历所有属性并重定义,对于大对象或频繁操作可能影响性能。
  4. 嵌套对象未处理 :如果属性值是对象,需要递归调用 observe 才能实现深层响应式。

改进示例(支持深层响应式)

javascript 复制代码
function observe(obj) {
    if (typeof obj !== 'object' || obj === null) return;

    for (const key in obj) {
        let internalValue = obj[key];
        observe(internalValue); // 递归处理嵌套对象
        Object.defineProperty(obj, key, {
            get: function () {
                console.log(`读取 ${key}: ${internalValue}`);
                return internalValue;
            },
            set: function (val) {
                console.log(`设置 ${key} 为 ${val}`);
                internalValue = val;
                observe(val); // 新值是对象时也转为响应式
            },
        });
    }
}
相关推荐
崔庆才丨静觅5 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅7 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊7 小时前
jwt介绍
前端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax