例子:

var arr = ["one","two","three"];

arr.forEach(function(part){
  part = "four";
  return "four";
})

alert(arr);

数组仍然是它的原始值,有任何方法来写访问数组的元素从迭代函数?


当前回答

让我们尽量保持简单,并讨论它是如何实际工作的。它与变量类型和函数参数有关。

下面是我们正在讨论的代码:

var arr = ["one","two","three"];

arr.forEach(function(part) {
  part = "four";
  return "four";
})

alert(arr);

首先,这里是你应该阅读关于Array.prototype.forEach()的地方:

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

其次,让我们简要地讨论一下JavaScript中的值类型。

基本类型(未定义,空,字符串,布尔,数字)存储一个实际值。

var x = 5;

引用类型(自定义对象)存储对象的内存位置。

例如:var xObj = {x: 5};

第三,函数参数是如何工作的。

在函数中,参数总是按值传递。

因为arr是一个字符串数组,它是一个基本对象数组,这意味着它们是按值存储的。

所以对于上面的代码,这意味着每次forEach()迭代时,part都等于arr[index]的相同值,但不是同一个对象。

Part = "four";改变部分变量,但不改变arr。

下面的代码将改变你想要的值:

var arr = ["one","two","three"];

arr.forEach(function(part, index) {
  arr[index] = "four";
});

alert(arr);

现在,如果数组arr是一个引用类型的数组,下面的代码将工作,因为引用类型存储的是对象的内存位置,而不是实际对象。

var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];

arr.forEach(function(part, index) {
  // part and arr[index] point to the same object
  // so changing the object that part points to changes the object that arr[index] points to

  part.num = "four";
});

alert(arr[0].num);
alert(arr[1].num);
alert(arr[2].num);

下面的例子说明了你可以改变part来指向一个新的对象,同时保留存储在arr中的对象:

var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];

arr.forEach(function(part, index) {
  // the following will not change the object that arr[index] points to because part now points at a new object
  part = 5;
});

alert(arr[0].num);
alert(arr[1].num);
alert(arr[2].num);

其他回答

Javascript是按值传递的,这本质上意味着部分是数组中值的副本。

要更改该值,请在循环中访问数组本身。

Arr [index] = '新值';

回调函数传递元素、索引和数组本身。

arr.forEach(function(part, index, theArray) {
  theArray[index] = "hello world";
});

edit -正如注释中所指出的,.forEach()函数可以接受第二个参数,它将在每次调用回调时用作this的值:

arr.forEach(function(part, index) {
  this[index] = "hello world";
}, arr); // use arr as this

第二个例子显示了在回调中arr本身是这样设置的。有人可能会认为.forEach()调用中涉及的数组可能是this的默认值,但不管出于什么原因,它不是;如果没有提供第二个参数,则没有定义。

(注意:如果回调函数是=>函数,上述内容并不适用,因为在调用此类函数时,它从未绑定到任何东西。)

同样重要的是要记住,Array原型上提供了一整套类似的实用程序,并且Stackoverflow上出现了许多关于某个函数或另一个函数的问题,因此最好的解决方案就是选择一个不同的工具。你有:

forEach用于对数组中的每个条目执行操作; 用于生成只包含符合条件的项的新数组的过滤器; 映射,通过转换现有数组来创建一个一对一的新数组; 一些用于检查数组中是否至少有一个元素符合某些描述; each用于检查数组中的所有条目是否与描述匹配; Find用于在数组中查找值

等等。MDN链接

将其替换为数组的索引。

array[index] = new_value;

如果您想删除项目

如果您需要做的更改是完全从列表中删除一个或多个项目,那么使用for循环并向后执行循环会更安全。

    for (let i = myArray.length - 1; i >= 0; i--)
    {
        const item = myArray[i];

        if (...) 
        {
           // remove item
           // https://stackoverflow.com/questions/5767325/how-can-i-remove-a-specific-item-from-an-array?rq=1
        }
    };

向后意味着每个项的数组永远不会改变。如果你继续循环并删除项目[3],那么项目[4]现在是新的项目[3],这不会让任何事情变得更容易。你不会让这个问题倒退。

这当然是一个不使用foreach的解决方案,但重要的是要记住,“老派”的方法往往是最好的。如果出于某种原因你需要分手;在循环中(有很多项),for循环更有效,因为不能跳出for循环。

foreach函数可以有一个回调函数(eachelement, elementIndex) 所以基本上你需要做的是:

arr.forEach(function(element,index){
    arr[index] = "four";   //set the value  
});
console.log(arr); //the array has been overwritten.

或者,如果您想保留原始数组,可以在执行上述过程之前对其进行复制。 要制作副本,您可以使用:

var copy = arr.slice();