执行 foreach 时更改数组中的值

新手上路,请多包涵

例子:

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

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

alert(arr);

数组仍然是它的原始值,有没有办法从迭代函数中对数组元素进行写访问?

原文由 rsk82 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 846
2 个回答

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

 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 。人们可能会认为 .forEach() 调用中涉及的数组可能是 this默认 值,但无论出于何种原因,它都不是;如果没有提供第二个参数, this 将是 undefined 的。

(注意:如果回调是 => 函数,则上述关于 this 的内容不适用,因为当调用此类函数时, this 永远不会绑定到任何东西。)

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

  • forEach 用于对数组中的每个条目进行操作;

  • filter 用于生成仅包含合格条目的新数组;

  • map 通过转换现有数组来制作一对一的新数组;

  • some 检查数组中的至少一个元素是否符合某些描述;

  • every 检查数组中的 所有 条目是否与描述匹配;

  • find 在数组中查找值

等等。 MDN 链接

原文由 Pointy 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

这是我们正在谈论的代码:

 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 中的值类型。

基元(undefined、null、String、Boolean、Number)存储实际值。

例如: var x = 5;

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

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

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

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

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

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

part = "four"; 将更改 part 变量,但将单独保留 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);

原文由 Dave 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题