问题分析:
在数组的 set 操作中,当设置的属性是数字时,会调用 setChangedValue 函数对变化值进行记录,并且将当前数组对象的副本作为值存入记录对象中。但是在处理对象类型属性时,没有进行类似操作。
因此,在修改数组中的对象类型元素时,由于没有进行深拷贝处理,导致最终生成结果中多出了一个{g:11}。
解决方法:
针对上述问题,在数组的 set 操作中需要对对象类型元素进行深拷贝,即使用 JSON.parse(JSON.stringify()) 方法进行转换,并将转换后的值存储到变化记录对象中。这样可以保证记录对象和原始数据之间不存在引用关系,避免互相影响。
代码修改如下:
const arrayHandler = (path) => ({
set: function (obj, prop, value) {
console.log(`属性 ${prop} 被设置为 ${value}`);
obj[prop] = value;
if (!isNaN(prop)) {
const copiedObj = JSON.parse(JSON.stringify(obj));
setChangedValue(changedValues, [...path, prop], copiedObj);
}
return true;
},
get: function (obj, prop) {
if (typeof obj[prop] === "object" && obj[prop] !== null) {
// 处理数组
if (Array.isArray(obj[prop])) {
return new Proxy(obj[prop], arrayHandler([...path, prop]));
}
// 处理对象
return new Proxy(obj[prop], handler([...path, prop]));
}
return obj[prop];
},
});
修改后,再次执行代码,生成的结果符合期望。




