javascript - 为什么不重新分配 forEach 中的参数元素起作用

对于以下代码块:

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

为什么在元素迭代时重新分配值不会更改数组中的对象?

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

但是通过使用索引访问它来改变它会改变数组中的对象吗?

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

更新数组中对象的最佳方式是什么? items2[i] 理想吗?

最佳答案

对参数重新分配说不!

这是对 JavaScript 等高级语言的一种基本理解。

Function parameters are temporary containers of a given value.

因此任何“重新分配”都不会改变原始值。

例如看下面的例子。

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);

如您所见,当您重新分配参数时,原始值将不会被触及。甚至还有一个不错的 Lint rule因为这是一个严重错误的区域。

突变在这里起作用,但是......

但是,如果您“改变”变量,这将起作用。

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);

所以回到您的代码片段。在 foreach 循环中发生的是每个数组项的“函数调用”,其中数组项作为参数传入。与上面的相似,在这里起作用的是变异。

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) 

但是,最好避免突变!

最好不要从this can lead to even more bugs开始变异.更好的方法是使用 map 并获取全新的对象集合。

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
})

https://stackoverflow.com/questions/70077292/

相关文章:

php - arc diff(Arcanist)因 env : php: No such file

c++ - 多线程段故障析构函数

c - 在两个源文件之间拆分类似函数的宏调用

angular - "declare global{ interface Window{ analy

python - 如何从带日期的字符串列表中过滤掉字符串?

scala - Scala 3 中的递归高阶函数类型

typescript - 如何防止将 Prop 传递给内部样式组件

clojure - 撤消覆盖 Clojure 中的内置函数

python - Ursina Python 引擎 : Lighting, 阴影和光晕效果

angular - 我需要取消订阅 Angular Observable 吗?