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.
原文:https://www.cnblogs.com/phpwechat/p/14764021.html