Home > Software design >  Understanding Behaviour of Find method in Javascript
Understanding Behaviour of Find method in Javascript

Time:12-06

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>

  • Related