JS中forEach()和map()的区别(请赐教)

1.forEach

(1)forEach()方法从到至尾遍历数组,为每个元素调用指定的函数;
(2)forEach()无法在所有元素有传递给调用的函数之前终止遍历;
(3)如果要提前终止,必须把forEach()方法放在一个try块中,并能抛出一个异常 。

	//传递的函数作为forEach()的第一个参数
	//然后forEach()使用三个参数调用该函数:数组元素、元素的索引和数组本身
    let arr = [1, 2, 3, 4, 5];
    arr.forEach((v, i, a) => a[i] = v * v);
    console.log(arr);//=>[1,4,9,16,25]

	//如果只关心数组的值,可以编写只有一个参数的函数,额外的参数将忽略
	let arr1 = [1, 2, 3, 4, 5];
    let sum = 0;
    arr1.forEach(item => sum += item);
    console.log(sum);//=>15

	//如果forEach()调用的函数抛出foreach.break异常,循环会提前终止
	    function foreach(a, f, t) {
        try {
            a.forEach(f, t);
        } catch (e) {
            if (e === foreach.break) return;
            else throw e;
        }
    }

    foreach.break = new Error("StopIteration");

2.map()

(1)map()方法将调用的数组的每个元素传递给指定的函数,并返回一个数组,它包含该函数的返回值;
(2)map()返回的是新数组,它不修改调用的数组;
(3)如果是稀疏数组,返回的也是相同的稀疏数组:它具有相同的长度,相同的缺失元素。

	let arr = [1, 2, 3];
    let b = arr.map(item => item * 2);//arr是[1, 2, 3];b是[2, 4, 6]

3.区别(重点)

(1)关于返回值
forEach():没有返回值,用console.log()打印是undefined。
map():有返回值,返回的是一个新数组(注意,不是函数的返回值),它包含函数的返回值。

    let arr1 = [1, 2, 3];
    let a = arr1.forEach((v, i, a) => a[i] = v * v);
    console.log(a);//=>undefined;没有返回值
    console.log(arr1);//=>[1, 4, 9];原数组会改变

    let arr2 = [1, 2, 3];
    let b = arr2.map(v => v * v);
    console.log(b);//=>[1, 4, 9];返回新数组
    console.log(arr2);//=>[1, 2, 3];原数组不会改变

(2)关于函数的参数(划重点,仔细看!
a.当函数的参数是3个(数组元素、元素的索引和数组本身)时,forEach()和map()的区别参照上面;
b.当函数的参数只有1个(数组元素)时,forEach()和map()的区别就大不相同了。

    let arr1 = [1, 2, 3];
    let a = arr1.forEach(item=>item+1);
    console.log(a);//=>undefined;没有返回值
    console.log(arr1);//=>[1, 2, 3];原数组不会改变

    let arr2 = [1, 2, 3];
    let b = arr2.map(item=>item+1);
    console.log(b);//=>[2, 3, 4];返回新数组
    console.log(arr2);//=>[1, 2, 3];原数组不会改变

我们可以看到,当用1个参数时,forEach()改变数组的值是没有效果的。
我们来看一种错误写法:

    let arr1 = [1, 2, 3];
    let a = arr1.forEach(function (item) {
        item = item + 1
    });
        console.log(a);//=>undefined;没有返回值
    console.log(arr1);//=>[1, 2, 3];原数组不会改变

因为传入的参数不可能既在左值里,又在右值里,这种赋值关系本身就是一种错误。
那么这样呢:

    let arr1 = [1, 2, 3];
    let a = arr1.forEach(function (item) {
    return item + 1
    });
    console.log(a);//=>undefined;没有返回值
    console.log(arr1);//=>[1, 2, 3];原数组不会改变

其实,函数本身是可以有返回值的,只是当只有1个参数时,forEach()没有办法使自身数组某个位置的值改变后,再赋值给该位置的元素。
我们来看:

    let arr1 = [1, 2, 3];
    let arr2 = [];
    let a = arr1.forEach(function (item) {
        arr2.push(item + 1)
    });
    console.log(a);//=>undefined;没有返回值
    console.log(arr1);//=>[1, 2, 3];原数组不会改变
    console.log(arr2);//=>[2, 3, 4];arr2拿到了经过处理的值

forEach()改变自身数组的时候是3个参数:通过数组本身调用索引确定位置,再通过将改变后的值赋值给该位置的元素来改变自身。
当只有一个参数时,map()也是因为赋值给了新数组,才看起来像是改变了原数组而已,其实原数组并没有改变。

    let arr1 = [1, 2, 3];
    let a = arr1.map(item=>item-1);
    console.log(a);//=>[0, 1, 2];a是新数组
    console.log(arr1);//=>[1, 2, 3];原数组不会改变

当是3个参数时,map()可以改变原数组,但返回的依然是新数组。

    let arr1 = [1, 2, 3];
    let a = arr1.map((v, i, a) => a[i] = v + 1);
    console.log(a);//=>[2,3,4];a依然是新数组
    console.log(arr1);//=>[2,3,4];原数组改变了

不信?我们来看:

    let arr1 = [1, 2, 3];
    let a = arr1.map((v, i, a) => a[i] = v + 1);
    console.log(a);//=>[5,3,4];a依然是新数组
    console.log(arr1);//=>[2,3,4];原数组改变了
    a[0] = 5;//赋值
    console.log(a);//=>[5,3,4];a是原数组
    console.log(arr1);//=>[2,3,4];原数组改变了

当重新赋值时,我们就能看到区别。a确实指向一个与arr1不同的数组。但为什么两个位置都变成5了呢?因为a本身是一个变量,它保存的并不是数组,而是一个指针。我们知道,数组是引用数据类型,变量只是保存了一个能找到它的地址,并且,大家找到的都是同一个。所以,一个地方改变了它,其他地方找到的也是改变之后的它。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值