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.