forEach()是否通过引用绑定?

Wot*_*els 9 javascript foreach pass-by-reference

var arr = ['Foo'];

arr.forEach(function(item){
  console.log(item);
  item = 'Lorem';
  console.dir(arr[0]);

});

for (var item in arr){
  arr[item] = 'Ipsum';
  console.dir(arr[0]);
}
Run Code Online (Sandbox Code Playgroud)

与上面的代码一样,我注意到更改传递给回调的项的值forEach()不会导致迭代对象发生更改.

for...in肯定使用.

为什么这样?我应该如何改变数组中的值?

我发现MDN上的主题很容易混淆

Fel*_*ing 12

用于......当然可以.

不,不.你的forEach循环等同于这个for...in循环(除了顺序):

for (var index in arr) {
  var item = arr[index];
  console.log(item);
  item = 'Lorem';
  console.dir(arr[0]);
}
Run Code Online (Sandbox Code Playgroud)

你看到数组也没有修改过吗?那是因为JavaScript总是按值传递,并且有一个非常简单的规则要记住:

为变量赋值永远不会更改另一个变量或数据结构的值.

这意味着,为其分配新值item,无法更改元素arr.如果要修改数组,则必须通过为索引赋值来直接改变它,即

arr[index] = 'foo';
Run Code Online (Sandbox Code Playgroud)

  • 我发现这听起来很混乱,因为对象**是通过引用传递的 (5认同)

Mch*_*chl 9

请注意,回调forEach函数有三个参数.第二个是当前元素的索引,第三个是数组本身.如果要修改数组,请使用这两个参数.


小智 5

在您的情况下,item变量是按值传递的,因为它具有原始值。如果它是一个json对象,并且您将更改其属性之一,它将反映在原始列表中。

在这种情况下,您可以使用forEachhas的其他参数。例如:

arr.forEach(element, index, array) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

使用这些参数,您可以直接影响 array[index]