Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在执行foreach时更改数组中的值_Javascript_Arrays_Foreach_Pass By Reference - Fatal编程技术网

Javascript 在执行foreach时更改数组中的值

Javascript 在执行foreach时更改数组中的值,javascript,arrays,foreach,pass-by-reference,Javascript,Arrays,Foreach,Pass By Reference,例如: var arr = ["one","two","three"]; arr.forEach(function(part){ part = "four"; return "four"; }) alert(arr); 数组仍保留其原始值,是否有任何方法可以从迭代函数中对数组元素进行写入访问?Javascript是按值传递的,这本质上意味着部分是数组中值的副本 array[index] = new_value; 要更改该值,请访问循环中的数组本身 arr[index]=“新值”回

例如:

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

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

alert(arr);

数组仍保留其原始值,是否有任何方法可以从迭代函数中对数组元素进行写入访问?

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

array[index] = new_value;
要更改该值,请访问循环中的数组本身


arr[index]=“新值”

回调被传递给元素、索引和数组本身

arr.forEach(function(part, index, theArray) {
  theArray[index] = "hello world";
});
编辑-如注释中所述,
.forEach()
函数可以接受第二个参数,该参数将在每次回调调用中用作
this
的值:

arr.forEach(function(part, index) {
  this[index] = "hello world";
}, arr); // use arr as this
第二个示例显示了在回调中将
arr
本身设置为
this
如果未提供第二个参数,则此
将是未定义的

(注意:如果回调函数是
=>
函数,则上述有关
的内容不适用,因为调用此类函数时,
从不绑定任何内容。)

同样重要的是要记住,在Array prototype上提供了一系列类似的实用程序,Stackoverflow上会弹出许多关于某个函数的问题,因此最好的解决方案是选择不同的工具。你有:

  • forEach
    用于对数组中的每个条目执行操作
  • 过滤器
    用于生成仅包含符合条件的条目的新数组
  • map
    用于通过转换现有数组来创建一对一的新数组
  • some
    检查数组中是否至少有一个元素符合某种描述
  • every
    检查数组中的所有条目是否与描述匹配
  • find
    在数组中查找值

等等

将其替换为数组的索引

array[index] = new_value;

.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();
让我们尽量保持简单,并讨论它实际上是如何工作的。它与变量类型和函数参数有关

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

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

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

alert(arr);
首先,这里是您应该阅读Array.prototype.forEach()的地方:

其次,让我们简要地谈谈JavaScript中的值类型

原语(未定义、空值、字符串、布尔值、数字)存储实际值

例如:
var x=5

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

例如:
var xObj={x:5}

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

在函数中,参数总是通过值传递

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

因此,对于上面的代码,这意味着每次forEach()迭代时,
part
等于与
arr[index]
相同的值,但不是相同的对象

第四部分
将更改
零件
变量,但将保持
arr
不变

以下代码将更改所需的值:

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

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

alert(arr);
现在,如果array
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);

使用数组对象方法可以修改数组内容,但与基本for循环相比,这些方法缺少一项重要功能。您不能在运行时修改索引

例如,如果要删除当前元素并将其放置到同一数组中的另一个索引位置,则可以轻松地执行此操作。如果您将当前元素移动到上一个位置,那么在下一次迭代中就不会出现问题,您将获得与未执行任何操作相同的下一项

考虑这段代码,当索引计数达到5时,我们将索引位置5处的项移动到索引位置2

var ar = [0,1,2,3,4,5,6,7,8,9];
ar.forEach((e,i,a) => {
i == 5 && a.splice(2,0,a.splice(i,1)[0])
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 5 5 - 6 6 - 7 7 - 8 8 - 9 9
var a = [0,1,2,3,4,5,6,7,8,9];
a.forEach((e,i,a) => {
i == 5 && a.splice(7,0,a.splice(i,1)[0])
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 5 5 - 6 7 - 7 5 - 8 8 - 9 9
然而,如果我们将当前元素移动到当前索引位置之外的某个位置,事情就会变得有点混乱。然后下一个项目将转移到移动项目的位置,在下一次迭代中,我们将无法看到或评估它

考虑这段代码,当索引计数达到5时,我们将索引位置5处的项移动到索引位置7

var ar = [0,1,2,3,4,5,6,7,8,9];
ar.forEach((e,i,a) => {
i == 5 && a.splice(2,0,a.splice(i,1)[0])
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 5 5 - 6 6 - 7 7 - 8 8 - 9 9
var a = [0,1,2,3,4,5,6,7,8,9];
a.forEach((e,i,a) => {
i == 5 && a.splice(7,0,a.splice(i,1)[0])
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 5 5 - 6 7 - 7 5 - 8 8 - 9 9
因此,我们从未在循环中遇到过6。通常,在for循环中,当您向前移动数组项时,您需要减小索引值,以便在下一次运行时索引保持在相同的位置,并且您仍然可以计算移动到移除项位置的项。这在数组方法中是不可能的。您不能更改索引。检查以下代码

var a = [0,1,2,3,4,5,6,7,8,9];
a.forEach((e,i,a) => {
i == 5 && (a.splice(7,0,a.splice(i,1)[0]), i--);
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 4 5 - 6 7 - 7 5 - 8 8 - 9 9
正如您所看到的,当我们递减
i
时,它不会从5开始继续,而是从原来的6开始


所以请记住这一点。

数组:
[1,2,3,4]

结果:
[“foo1”、“foo2”、“foo3”、“foo4”]

保留原始数组
const originalArr=[“铁”、“超级”、“蚂蚁”、“水族”];
constmodifidarr=originalArr.map(name=>`${name}man`);
日志(“原始:%s”,originalArr);

日志(“已修改:%s”,修改器)通过扩展zhujy_8833 slice()的建议来迭代副本,添加或删除会改变索引的元素,sim
if (value === "A3" || value === "A4" || value === "A7") {
    values.splice(index, 1, 'newVal');
};

// Expected: [ 'A0', 'A1', 'A2', 'newVal', 'newVal', 'A5', 'A6', 'newVal', 'A8' ]
var data = [1,2,3,4];
data.forEach( (item, i, self) => self[i] = item + 10 );
[11,12,13,14]
data.forEach( (item,i) => data[i] = item + 10);
var newArray= [444,555,666];
var oldArray =[11,22,33];
oldArray.forEach((name, index) => oldArray [index] = newArray[index]);
console.log(newArray);