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);
8 回答
Javascript是按值传递的,这实质上意味着
part
是数组中值的副本 .要更改值,请在循环中访问数组本身 .
arr[index] = 'new value';
要完全添加或删除会改变索引的元素,通过扩展zhujy_8833 slice()的建议迭代副本,只需计算已删除或添加的元素数量并相应地更改索引 . 例如,要删除元素:
要在之前插入元素:
要在以下后插入元素:
要替换元素:
注意:如果同时实现'before'和'after'插入,代码应首先处理'before'插入,其他方式不会如预期
.forEach函数可以有一个回调函数(eachelement,elementIndex)所以基本上你需要做的是:
或者,如果要保留原始数组,可以在执行上述过程之前复制它 . 要制作副本,您可以使用:
回调传递元素,索引和数组本身 .
编辑 - 如注释中所述,
.forEach()
函数可以采用第二个参数,该参数将在每次调用回调时用作this
的值:第二个示例显示
arr
本身在回调中被设置为this
. 有人可能认为.forEach()
调用中涉及的数组可能是this
的默认值,但无论出于何种原因,它都不是;如果没有提供第二个参数,this
将为undefined
.另外重要的是要记住,在Array原型上提供了一整套类似的实用程序,Stackoverflow上有很多关于一个或另一个函数的问题,因此最好的解决方案就是选择一个不同的工具 . 你有:
forEach
用于对数组中的每个条目执行操作;filter
用于生成仅包含限定条目的新数组;map
用于通过转换现有数组来创建一对一的新数组;some
检查数组中是否至少有一个元素符合某些描述;every
检查数组中的所有条目是否与描述匹配;find
在数组中查找值等等 . MDN link
用数组的索引替换它 .
使用Array对象方法,您可以修改Array内容,但与基本for循环相比,这些方法缺少一个重要功能 . 您无法在运行时修改索引 .
例如,如果要删除当前元素并将其放置在同一个数组中的另一个索引位置,则可以轻松执行此操作 . 如果将当前元素移动到先前位置,则在下一次迭代中没有问题,您将获得相同的下一个项目,就像您没有做任何事情一样 .
考虑这个代码,我们将索引位置5的项目移动到索引位置2,一旦索引计数到5 .
但是,如果我们将当前元素移动到当前索引位置之外的某个位置,事情就会变得有些混乱 . 然后,下一个项目将转移到移动的项目位置,在下一次迭代中,我们将无法查看或评估它 .
考虑这个代码,我们将索引位置5处的项目移动到索引位置7,一旦索引计数到5 .
所以我们从来没有在循环中遇到过6 . 通常在for循环中,当向前移动数组项时,预期会减小索引值,以便索引在下一次运行中保持在相同位置,并且仍然可以评估移动到已移除项目位置的项目 . 这对阵列方法是不可能的 . 你不能改变索引 . 检查以下代码
正如你所看到的那样,当我们减少
i
时,它将不会从5,而是从它离开的地方继续 .所以请记住这一点 .
让我们试着保持简单,并讨论它是如何工作的 . 它与变量类型和函数参数有关 .
这是我们正在讨论的代码:
首先,这里是您应该阅读的有关Array.prototype.forEach()的内容:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
其次,让我们简单地谈谈JavaScript中的值类型 .
Primitives (undefined,null,String,Boolean,Number)存储实际值 .
例如:
var x = 5;
Reference Types (自定义对象)存储对象的内存位置 .
例如:
var xObj = { x : 5 };
第三,函数参数如何工作 .
在函数中,参数按值传递 always .
因为
arr
是一个字符串数组,它是一个 primitive 对象的数组,这意味着它们是按值存储的 .因此,对于上面的代码,这意味着每次forEach()迭代时,
part
等于与arr[index]
相同的值, but not the same object .part = "four";
将更改part
变量,但将单独留下arr
.以下代码将更改您想要的值:
现在,如果array
arr
是 reference types 的数组,则以下代码将起作用,因为引用类型存储对象的内存位置而不是实际对象 .以下说明您可以将
part
更改为指向新对象,同时将对象保留在arr
中:数组:
["1", 2, 3, 4]
结果:
["foo1", "foo2", "foo3", "foo4"]
Array.prototype.map()保留原始数组
通过引入新变量
modifiedArr
实现Array.prototype.map()修改原始数组
通过重新分配
arr
变量来实现Array.prototype.forEach()修改原始数组
通过索引
arr[i]
定位它的键来实现