例子:
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);
该数组仍然具有其原始值,有什么方法可以从迭代函数中写入对数组元素的访问权限?
回调传递元素、索引和数组本身。
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链接
让我们尽量保持简单并讨论它是如何实际工作的。它与变量类型和函数参数有关。
这是我们正在谈论的您的代码:
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";
会改变part
变量,但会离开arr
。
以下代码将更改您想要的值:
var arr = ["one","two","three"];
arr.forEach(function(part, index) {
arr[index] = "four";
});
alert(arr);
现在如果 arrayarr
是一个引用类型数组,下面的代码将起作用,因为引用类型存储对象的内存位置而不是实际对象。
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);
数组:[1, 2, 3, 4]
结果:["foo1", "foo2", "foo3", "foo4"]
Array.prototype.map()
保留原始数组const originalArr = ["Iron", "Super", "Ant", "Aqua"];
const modifiedArr = originalArr.map(name => `${name}man`);
console.log( "Original: %s", originalArr );
console.log( "Modified: %s", modifiedArr );
Array.prototype.forEach()
覆盖原始数组const originalArr = ["Iron", "Super", "Ant", "Aqua"];
originalArr.forEach((name, index) => originalArr[index] = `${name}man`);
console.log( "Overridden: %s", originalArr );
Javascript 是按值传递的,这实质上意味着part
是数组中值的副本。
要更改该值,请在循环中访问数组本身。
arr[index] = 'new value';
这是使用=>
样式函数的类似答案:
var data = [1,2,3,4];
data.forEach( (item, i, self) => self[i] = item + 10 );
给出结果:
[11,12,13,14]
该self
参数不与箭头样式功能绝对必要的,所以
data.forEach( (item,i) => data[i] = item + 10);
也有效。