let arr = [{ age: 3 }, { age: 5 }, { age: 6 }, { age: 7 }];
let exists = arr.find(x => x.age < 4);
exists.age = 1;
console.log(arr);
//output is [{age:4},{age:5},{age:6},{age:7}];
In the above example, I'm updating the result returned by the find method but it also changes the value of the original array why so?
CodePudding user response:
Array.prototype.find
will return the first element that satisfy the condition that you've passed as a callback function.
Since you are looking for an object whose age
property is less than 4
. So It will return first object(whose age
is 3
). So if you gonna check for equality of exists
and arr[0]
then It will return object that satisfy the condition
let arr = [{ age: 3 }, { age: 5 }, { age: 6 }, { age: 7 }];
let exists = arr.find((x) => x.age < 4);
console.log(exists === arr[0])
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
So, If you are going to do any kind of mutation with the object that is returned by the find
method then the original object will reflect the changes.
Because both are same object just different references.
If you don't want to mutate the original object then you should clone it before doing any kind of changes to that object.
Note: Both of the following method does shallow copy
1) Using spread syntax
let arr = [{ age: 3 }, { age: 5 }, { age: 6 }, { age: 7 }];
let exists = arr.find((x) => x.age < 4);
const clone = { ...exists };
clone.age = 1;
console.log(arr);
/* This is not a part of answer. It is just to give the output full height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
2) Using Object.assign
let arr = [{ age: 3 }, { age: 5 }, { age: 6 }, { age: 7 }];
let exists = arr.find((x) => x.age < 4);
const clone = Object.assign({}, exists);
clone.age = 1;
console.log(arr);
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Because you have an array of object references. In JavaScript, objects are actually stored elsewhere (called the "heap") and object variables actually only contain the references to object. So the reason is because you're updating the same object.
If you want to do a shallow clone of an object, you can use Object.assign({}, obj)
.
Further, not directly relevant to your question, if your object properties themselves were to contain other object references, including arrays, and you want those to be copies as well, you'll have to deep-clone them. This is not automatically done by a stock JavaScript function or method. You'll have to find code that does that for you or write it yourself. Last time I did this, I used randa's clone function because a different developer on my team had already imported the ramda library into our project. What makes the most sense for your project may be different.
CodePudding user response:
It's because Objects in JavaScript are passed by reference, you got that object ( {age : 3} ) in exists then added 1 to it's "age" key , so the original object also changed .
let obj1 = {age: 3 , name: 'jack' }
let obj2 = obj1
console.log(obj1 === obj2 ) // true
// if you change the second object , the first one will change too :
obj2.age = 15
console.log(obj1 , obj2 )
// obj1 = { age: 15 , name: 'jack' }
// obj2 = { age: 15 , name: 'jack' }
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>