这是因为在数组中修改元素时,调用了 setChangedValue 方法,它会将整个数组替换成一个新的数组,并把该新数组设置到对应的路径上。所以当你在修改 f[2].g 时,实际上已经创建了一个新的数组 [10, 5, {g: 11}] 并赋值给了 f 对应的路径。
为了解决这个问题,可以在 arrayHandler.set 方法中判断是否仅仅修改了某个元素而不是整个数组。如果是单独修改某个元素,则只需要更新对应元素即可,否则还需按原来的逻辑重新创建一个新的数组并将其赋值给对应路径。
具体实现代码如下:
const arrayHandler = (path) => ({
set: function (obj, prop, value) {
console.log(`属性 ${prop} 被设置为 ${value}`);
if (!isNaN(prop)) {
// 如果是数字类型,则说明是修改某个元素
obj[prop] = value;
setChangedValue(changedValues, [...path, prop], value);
} else {
// 否则需要重新创建一个新的数组
const newArr = Array.from(obj);
newArr[prop] = value;
obj.splice(0, obj.length, ...newArr);
setChangedValue(changedValues, [...path], newArr);
}
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];
},
});




