郑州专业网站制作的公司哪家好,广州网站备案要求,制作网站的全过程,工作室暴利项目1#xff0c;定义和用法
定义#xff1a; forEach() 方法用于调用数组的每个元素#xff0c;并将元素传递给回调函数。注意: forEach() 对于空数组是不会执行回调函数的。 用法#xff1a;
// 箭头函数
forEach((element) { /* … */ })
forEach((element, index) 定义和用法
定义 forEach() 方法用于调用数组的每个元素并将元素传递给回调函数。注意: forEach() 对于空数组是不会执行回调函数的。 用法
// 箭头函数
forEach((element) { /* … */ })
forEach((element, index) { /* … */ })
forEach((element, index, array) { /* … */ })// 回调函数
forEach(callbackFn)
forEach(callbackFn, thisArg)// 内联回调函数
forEach(function(element) { /* … */ })
forEach(function(element, index) { /* … */ })
forEach(function(element, index, array){ /* … */ })
forEach(function(element, index, array) { /* … */ }, thisArg)片2forEach是否会改变原数组
结论对于简单数据类型是不会改变原数组的对于复杂数据类型的直接赋值操作则是可以改变原数组的;
1简单数据类型不会改变原数组 const arrNumber [1, 2, 3, 4];arrNumber.forEach((item,index){item item*2})console.log(arrNumber:,arrNumber); // [1, 2, 3, 4]const arrString [Eula,Kaya,Umbar]arrString.forEach((item,index){item item_index})console.log(arrString:,arrString);// [Eula,Kaya,Umbar]那我如果就是想要改变原数组可以这样写 const arrNumber [1, 2, 3, 4];arrNumber.forEach((item,index,arr){if(item % 2 0){console.log(可以被2整除的需要重新赋值:,item);arr[index] 100/}})console.log(arrNumber:,arrNumber);//[1, 100, 3, 100]直接 arr[index] 相当于你平常的 数组名[第几项] 值。这样自然是可以修改原数组的
2引用数据类型直接对其直接赋值能够改变原数组
const list [{ name: Kaya, age: 18 },{ name: Eula, age: 19 },{ name: Umbar, age: 20 }];// 直接进行赋值是可以改变原数组的 改变姓名list.forEach((item, index) {if (item.name Eula) {item.name Xinjie;}});// 改变年龄list.forEach((item, index) {item.age;});console.log(list:, list);打印如下0:{name: Kaya, age: 19}1: {name: Xinjie, age: 20}2: {name: Umbar, age: 21}forEach() 相当于把原数组拷贝出来对拷贝出来的数据进行操作因为基本类型的数据相当于深拷贝引用数据是浅拷贝相当于只拷贝了指针地址更改数据也会连带把原数组给改掉
对于基本数据类型number,string,Boolean,null,undefined它们在栈内存中直接存储变量与值。 而Object对象的真正的数据是保存在堆内存栈内只保存了对象的变量以及对应的堆的地址所以操作Object其实就是直接操作了原数组对象本身。
3除了抛出异常以外无法中止或跳出循环
forEach对数组进行遍历时不能使用break或return等关键字跳出循环使用return只能跳过本次循环相当于continue。
1使用return 跳出本次循环 var arr [1, 2, 3, 4, 5];arr.forEach(function (item) {// 只能跳出本次循环if (item 3) {return;}console.log(item:,item); // 1 2 4 5});2抛出错误跳出终止整个循环不推荐使用
var arr [1, 2, 3, 4, 5];try {arr.forEach(function (item) {// 只能跳出本次循环if (item 3) {throw new Error(主动跳出循环);}console.log(item:, item); // 1 2 });} catch (error) {console.log(error:, error);}注意抛出异常虽然能够跳出整个循环体但需要try catch函数来捕获此异常否则控制台报错将会阻断代码的向下执行
3forEach()方法不支持使用break或continue语句来跳出循环或跳过某一项。
如果需要跳出循环或跳过某一项应该使用for循环或其他支持break或continue语句的方法。
4不能处理异步函数async await
1先看下面这个案例
async function test() {let arr [3, 2, 1]arr.forEach(async item {const res await mockSync(item)console.log(res)})console.log(end)
}function mockSync(x) {return new Promise((resolve, reject) {setTimeout(() {resolve(x)}, 1000 * x)})
}
test()
我们期望的结果是:
3
2
1
end
但是实际上会输出:
end
1
2
32针对上面问题可以有以下两种解决方案
第一种使用普通的for循环语法 function mockSync(x) {return new Promise((resolve, reject) {setTimeout(() {resolve(x);}, 1000 * x);});}// 使用for循环async function test(){let arr [3, 2, 1];for(let i0;iarr.length;i){const res await mockSync(arr[i]);console.log(res);}}test();// 3,2,1现在执行顺序是正常的等待3秒后打印3然后等待2秒后打印2最后等待1秒后打印1
第二种使用for of 循环来处理异步函数 function mockSync(x) {return new Promise((resolve, reject) {setTimeout(() {resolve(x);}, 1000 * x);});}// 使用for of 循环async function test() {let arr [3, 2, 1];for (const item of arr) {const res await mockSync(item);console.log(res:,res);}}test();