# JavaScript 数据代理实现文档

## 一、基本概念

数据代理是指通过一个对象（代理对象）间接访问和操作另一个对象（目标对象）的属性。本示例展示了如何使用 `Object.defineProperty` 实现简单的数据代理。

## 二、代码实现解析

```javascript
let obj1 = { x: 100 };  // 目标对象（被代理对象）
let obj2 = { y: 200 };  // 代理对象

// 在obj2上定义x属性的代理
Object.defineProperty(obj2, "x", {
    get() {
        return obj1.x;  // 读取时返回obj1的x属性
    },
    set(value) {
        obj1.x = value; // 设置时修改obj1的x属性
    }
});
```

## 三、核心机制说明

1. **代理原理**：
   - 通过 `Object.defineProperty` 在代理对象（obj2）上定义新属性
   - 使用 getter/setter 方法实现对目标对象（obj1）属性的间接访问

2. **访问流程**：
   - 读取 `obj2.x` → 触发 getter → 返回 `obj1.x` 的值
   - 设置 `obj2.x` → 触发 setter → 将值赋给 `obj1.x`

3. **特性**：
   - 透明的属性访问（使用者无需知道代理存在）
   - 可以在访问前后执行额外逻辑（如验证、日志等）

## 四、应用场景

| 场景     | 说明                 | 示例                           |
| -------- | -------------------- | ------------------------------ |
| 属性转发 | 跨对象访问属性       | 本示例实现                     |
| 数据验证 | 设置属性前检查有效性 | setter中添加验证逻辑           |
| 访问控制 | 限制某些属性的访问   | getter中添加权限检查           |
| 日志记录 | 跟踪属性访问         | getter/setter中添加console.log |

## 五、扩展实现

### 1. 多属性代理
```javascript
function proxyProperties(target, source, props) {
    props.forEach(prop => {
        Object.defineProperty(target, prop, {
            get() {
                return source[prop];
            },
            set(value) {
                source[prop] = value;
            }
        });
    });
}

// 使用示例
proxyProperties(obj2, obj1, ['x', 'a', 'b']);
```

### 2. Vue2 风格的数据代理
```javascript
function observe(obj) {
    const handler = {
        get(target, prop) {
            console.log(`读取 ${prop}`);
            return target[prop];
        },
        set(target, prop, value) {
            console.log(`设置 ${prop} 为 ${value}`);
            target[prop] = value;
            return true;
        }
    };
    return new Proxy(obj, handler);
}

const observed = observe(obj1);
```

## 六、注意事项

1. **性能考虑**：
   - 每个代理属性都会增加访问开销
   - 避免在性能关键路径上过度使用

2. **引用关系**：
   - 代理对象和目标对象保持独立
   - 修改代理属性会影响原始对象

3. **枚举特性**：
   - 默认情况下代理属性不可枚举
   - 需要显式设置 `enumerable: true`

4. **兼容性**：
   - `Object.defineProperty` 是 ES5 特性
   - 现代开发可考虑使用 ES6 Proxy
