ES6的Proxy代理多层结构数据 触发set方法的坑

Proxy代理多层结构Demo

//需要被代理的数据
var data = [
  { name: "小明", age: 12 }, { name: "小红", age: 15 }, { name: "小蓝", age: 17 }
];
//代理后的数据对象 操作proxyData会影响data数据,但直接更改data不会触发get和set方法
const proxyData = new Proxy(data, {
  get(obj, index) {
    return obj[index];
  },
  set: function (target, key, value) {
    target[key] = value;
    return true;
  });

假设给proxyData[0][“name”]=“小明_修改后” 不会触发proxyData的set方法,因为proxyData[0]对象的指向没有变。
目前我解决的方法是:在赋值的时候
let obj=proxyData[0];
obj[“name”]=“小明_修改后”;
proxyData[0]=obj;
这种方法可以修改proxyData[0]对象的指向obj,从而触发set方法,但这种方法有一定局限性,当我们的数据有更多未知层的时候修改内层数据还是无法触发set方法。
然后在原来基础加一个递归,通过递归触发set

function deepProxy(obj, cb) {

  if (typeof obj === 'object') {

    for (let key in obj) {
      if (typeof obj[key] === 'object') {
        obj[key] = deepProxy(obj[key], cb);
      }
    }

  }

  return new Proxy(obj, {

    /**
     * @param {Object, Array} target 设置值的对象
     * @param {String} key 属性
     * @param {any} value 值
     * @param {Object} receiver this
     */
    set: function (target, key, value, receiver) {

      if (typeof value === 'object') {
        value = deepProxy(value, cb);
      }

      let cbType = target[key] == undefined ? 'create' : 'modify';

      //排除数组修改length回调
      if (!(Array.isArray(target) && key === 'length')) {
        cb(cbType, { target, key, value });
      }
      return Reflect.set(target, key, value, receiver);

    },
    deleteProperty(target, key) {
      cb('delete', { target, key });
      return Reflect.deleteProperty(target, key);
    }

  });

}
// 数组测试
let a = deepProxy([], (type, data) => {
  console.log(type, data);
});

a.push(1)
a.push({ a: 1 })

// 对象测试
let b = deepProxy({}, (type, data) => {
  console.log(type, data);
});

b.name = '大花猫花大';
b.info = {
  age: 10,
  data: {
    data: {
      data: {
        text: 1
      }
    }
  }
}

delete b.info.age;

另外如果在"use strict"严格模式下,set方法需要返回true.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值