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.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章