JS foreach遍历修改对象的问题
为什么第一个修改起作用(当我重新调整对象的属性时)而不是第二个(当我重新分配整个对象时)?
const arr1 = [
{ id: 1, value: 1 },
{ id: 2, value: 2 },
{ id: 3, value: 3 },
{ id: 4, value: 4 },
{ id: 5, value: 5 },
]
arr1.forEach((item, index) => {
if (item.id === 1) {
item.value *= 10 // modify success
}
});
console.log(arr1);
arr1.forEach((item, index) => {
if (item.id === 1) {
item = {id:6,value:6} // modify fail
}
});
console.log(arr1);
.as-console-wrapper { max-height: 100% !important; top: auto; }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
考虑以下示例:
我们创建一个对象并将其分配给变量
foo
,然后我们将foo
分配给bar
。因此,现在foo
和bar
请参阅以下图所示的同一对象。接下来,让我们更改分配给
bar
的对象的val
字段。我们注意到更改反映了变量foo
和bar
,这是因为两个变量都涉及同一对象。接下来,我们将一个新对象分配给
bar
。请注意,这不会影响foo
引用的对象,bar
现在只是指另一个对象。让我们将其与您的问题中的示例相关联。因此,在
foreach
循环的每次迭代中,item
在回调函数中的参数从数组中指向对象,当您从此item更改字段时
参数它更改数组中的对象,但是当您将item
分配给新对象时,它对存储在数组中的对象没有任何作用。如果您想用新对象替换整个对象,则可以采用几种方法,其中两种如下:
MAP
,并创建一个更换该对象的新数组。Consider the example below:
We create an object and assign it to variable
foo
and then we assignfoo
tobar
. So, now bothfoo
andbar
refer to the same object, as illustrated in the diagram below.Next let's change the
val
field of the object i.e. assigned tobar
. We notice that the change is reflected by both the variablesfoo
andbar
and this is because both the variables refer to the same object.Next we assign a new object to
bar
. Notice this doesn't effect the object thatfoo
refers to,bar
is simply now referring to a different object.Let's relate this to the
forEach
example in your question. So, in every iteration of theforEach
loop, theitem
argument in the callback function points to an object from the array and when you change a field from thisitem
argument it changes the object in the array but when you assignitem
to a new object it does nothing to the object stored in the array.If you want to replace the entire object with a new one, there are several approaches you could take, two of which are mentioned below:
map
over the array and create a new array with that one object replaced.您的混乱是自然的,这与实际对象和变量之间的区别有关。
在您的foreach函数中,您有一个变量“项目”,该变量指向您要循环的数组中的对象。但是,当您运行时,
您不是在修改对象,而是将变量“项目”指向您刚刚创建的新对象。
如果要更改实际对象本身,则可以通过一个一个一个一个一个一个一个地修改值或使用object.sign从另一个对象复制的值来手动执行此操作。
在此片段中,我做了一些示例,希望可以说明差异,最后您使用对象解决了特定案例。分配()
Your confusion is natural, and it's to do with the difference between the actual object, and the variable.
In your foreach function, you have a variable "item" which points to the object in the array you are looping. But when you run
You are not modifying the object, but rather making the variable "item" point to a new object that you've just created.
If you want to change the actual object itself, you can do it manually by modifying the values one by one, or by copying from another object using Object.assign.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
In this snippet, I've made a few examples that hopefully illustrate the differences, and at the end your specific case being solved using Object.assign()
因为
item
是对当前正在迭代的对象的引用,因此修改参考将依次修改原始对象(因此在第一个代码示例中观察到的行为)。在第二个中,您只需重新分配对全新对象的引用,因此您无法再修改您要迭代的原始对象。基本上,当您用
foreach
循环循环时, item 是一个变量,其当前值是指向当前迭代的对象的引用/指针。修改此对象会修改原始对象(因为它只是一个参考,而不是实际的克隆对象)。但是,当您重新分配它时,该引用不再存在,因为item
具有指向的新值。您可以像这样修改它,成功:您也可以通过循环浏览要重新分配的每个属性,也可以动态地做到这一点:
Because
item
is a reference to the object that's currently being iterated over, modifying the reference will in turn modify the original object (hence the behaviour observed in your first code example). In the secondforEach
you just reassign the reference to a brand new object so you can no longer modify the original object you were iterating over.Basically, when you loop over the array with
forEach
,item
is a variable whose current value is a reference/pointer to the object currently being iterated over. Modifying this object modifies the original (as it's just a reference, not an actual cloned object). However, when you reassign it, the reference is no longer present becauseitem
has a new value that it points to. You could modify it like so, with success:You could do it dynamically as well, by looping over each property you wish to reassign like so:
对于第一种情况,可以理解为:
第二种情况:
For the first case, it can be understood as:
second case: