I have a function that takes an object and returns a proxied version of this object, which can be mutated without affecting the original object.
const createProxy4 = (obj) => {
const handler = {
get(target, prop) {
//if the value of a property is an object - replace it with another proxy before return
if (target[prop] !== null && typeof target[prop] === "object") {
target[prop] = new Proxy({ ...target[prop] }, handler);
}
//if the value is a primitive - just return it
return target[prop];
},
set(target, prop, value) {
//to update the property - just assign a new value to it
target[prop] = value;
return true;
},
};
//create a shallow copy of the original object
return new Proxy({ ...obj }, handler);
};
Example
//here is an original object
const obj8 = {
x: { y: 5 },
};
//let's create a proxied copy of it
const proxy8 = createProxy4(obj8);
//let's change the property of the proxied object
proxy8.x.y = 27;
console.log(obj8); //{ x: { y: 5 } } - original object is not affected
console.log(proxy8); //{ x: { y: 27 } } - proxied object property is changed as expected
//let's change proxy using expression which uses it's own property
proxy8.x.y = proxy8.x.y + 2;
console.log(obj8); //{ x: { y: 5 } } - original object is not affected
console.log(proxy8); //{ x: { y: 27 } } - NOTHING CHANGED! WHY?
//let's refactor the previous expression using an intermediate variable "t"
const t = proxy8.x.y + 2;
proxy8.x.y = t;
console.log(obj8); //{ x: { y: 5 } } - original object is not affected
console.log(proxy8); //{ x: { y: 29 } } - Changes applied as expected. WHY?
Question
So, from my point of view, expressions
proxy8.x.y = proxy8.x.y + 2;
//doesn't work
and
const t = proxy8.x.y + 2;
proxy8.x.y = t;
//works
are almost identical.
But why one of them doesn't work? Why does an expression that contains a deeply nested proxy object property not update the same proxy object property?
console.log(`Cloning ${prop}`);in the line before{ ...target[prop] }and you'll see what's happening