Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

282
Views
why doesn't reassigning the parameter element in forEach work

Not much explanation here so Ill just get straight to the point.

For the following code block:

const items = [
  { id: 1, name: 'one' },
  { id: 2, name: 'two' },
];

const changes = {
  name: 'hello'
}

items.forEach((item, i) => {
  item = {
    ...item,
    ...changes
  }
})

console.log(items) // items NOT reassigned with changes

items.forEach((item, i) => {
  items[i] = {
    ...item,
    ...changes
  }
});

console.log(items) // items reassigned with changes

Why does reassigning the values right on the element iteration not change the objects in the array?

  item = {
    ...item,
    ...changes
  }

but changing it by accessing it with the index does change the objects in the array?

  items2[i] = {
    ...item,
    ...changes
  }

and what is the best way to update objects in an array? is items2[i] ideal?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Say no to param reassign!

This is a sort of a fundamental understanding of higher level languages like JavaScript.

Function parameters are temporary containers of a given value.

Hence any "reassigning" will not change the original value.

For example look at the example below.

let importantObject = {
  hello: "world"
}

// We are just reassigning the function parameter
function tryUpdateObjectByParamReassign(parameter) {
  parameter = {
    ...parameter,
    updated: "object"
  }
}


tryUpdateObjectByParamReassign(importantObject)
console.log("When tryUpdateObjectByParamReassign the object is not updated");
console.log(importantObject);

As you can see when you re-assign a parameter the original value will not be touched. There is even a nice Lint rule since this is a heavily bug prone area.

Mutation will work here, but ....

However if you "mutate" the variable this will work.

let importantObject = {
  hello: "world"
}

// When we mutate the returned object since we are mutating the object the updates will be shown
function tryUpdateObjectByObjectMutation(parameter) {
  parameter["updated"] = "object"
}


tryUpdateObjectByObjectMutation(importantObject)
console.log("When tryUpdateObjectByObjectMutation the object is updated");
console.log(importantObject);

So coming back to your code snippet. In a foreach loop what happens is a "function call" per each array item where the array item is passed in as a parameter. So similar to above what will work here is as mutation.

const items = [
  { id: 1, name: 'one' },
  { id: 2, name: 'two' },
];

const changes = {
  name: 'hello'
}

items.forEach((item, i) => {
  // Object assign just copies an object into another object
  Object.assign(item, changes);
})

console.log(items) 

But, it's better to avoid mutation!

It's better not mutate since this can lead to even more bugs. A better approach would be to use map and get a brand new collection of objects.

const items = [{
    id: 1,
    name: 'one'
  },
  {
    id: 2,
    name: 'two'
  },
];

const changes = {
  name: 'hello'
}

const updatedItems = items.map((item, i) => {
  return {
    ...item,
    ...changes
  }
})

console.log({
  items
})
console.log({
  updatedItems
})

about 4 years ago · Juan Pablo Isaza Report

0

As the MDN page for forEach says:

forEach() executes the callbackFn function once for each array element; unlike map() or reduce() it always returns the value undefined and is not chainable. The typical use case is to execute side effects at the end of a chain.

Have a look here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

This means that although you did create new object for item, it was not returned as a value for that index of array. Unlike your second example, the first one is not changing original array, but just creates new objects and returns undefined. This is why your array is not modified.

about 4 years ago · Juan Pablo Isaza Report

0

I'd go with a classic Object.assign for this:

const items = [
  { id: 1, name: 'one' },
  { id: 2, name: 'two' },
];

const changes = {
  name: 'hello'
}

items.forEach( (item) => Object.assign(item,changes) )

console.log(items) 

Properties in the target object are overwritten by properties in the sources if they have the same key. Later sources' properties overwrite earlier ones. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!