回调函数的重构

forEach

map



var arr=[1,2,3,4,5];

function forEach(fn){
	for(var i=0;i<arr.length;i++){
		//调用
		fn(arr[i],i,arr);
	}
}
function callBack(item,index,arr){
	//这是我自己写的回调函数
	console.log(item);
}

forEach(callBack);

类似于:

forEach(function(item,index,arr){
	console.log(item);
});

这里是匿名函数。
所以这里没有区别,就直接传递

map



var arr=[];
function map(fn){
	var arr1=[];
	for(var i=0;i<arr.length;i++){
		if(i in arr){
			var item = fn(arr[i],i,arr);
			arr1[i] = item;
		}
	}
	return arr1;
}
function callBack(item,index,arr){
	//这是我自己写的回调函数
	console.log(item);
	//返回什么完全凭自己喜好
	return item;
}

map(callBack);

类似于:

map(function(item,index,arr){
	console.log(item);
	return item;
});

这里是匿名函数。
所以这里没有区别,就直接传递

1.map是浅拷贝。
2.map,forEach自动忽略空值。
在这里插入图片描述
我理解大多数人迫切想要在forEach里加break;的决心。
那就用for他不香么?


        var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
        for (var i = 0; i < arr.length;) {
            if (arr[i] % 2 === 0 && arr[i] % 3 === 0) {
                arr.splice(i, 1);
                continue;
            }
            i++
        }
        arr.forEach(function (item, index) {
            console.log(item);
            if (item % 2 === 0 && item % 3 === 0) {
                //错误啊,唉
                arr.splice(index, 1);
            }
        });
        console.log(arr);

方法1


       arr.forEach(function (item, index, array) {

            if (item % 2 === 0 && item % 3 === 0) {

                arr.splice(index, 1);
                //错误,[6,12,6,6,6,12] 12删除不了
                var i;
                while ((i = array.indexOf(item)) !== -1) {
                    arr.splice(i, 1);
                }
            }

        });

方法2


       arr.forEach(function (item, index, array) {

            if (item % 2 === 0 && item % 3 === 0) {

                arr.splice(index, 1);
                //错误,index是函数内部的局部变量,是复制而不是地址,
                //所以改变不了增强for循环里面的i。
                index--;
            }

        });

教训和总结

forEach()就是单纯的遍历,且因为for有i++必须执行的条件,(即使加了continue,break不行),所以你没办法改变系统forEach中i的值。forEach就是会忠诚地执行这个循环直到数组结束,期间你删除了一个元素,那你就错过了下一个元素。因为下一个元素的索引变成了本轮的这个元素的索引。而且用forEach你没办法清楚这个数组,假设你是用pop()删的,你每次删后,你的长度就减少。但是你删的是最后1个,但是你已经从左到右走到下一个了,那么你走过的那个就永远不会被删除。

简而言之,forEach这种封装很好的执行了桥接模式,我就是干遍历这么一件事。你不管回调函数里怎么搞,都不会影响我的实现。即使我给你了arr这个指针,你可能对我改变,但由于我不等人的特性,你改变了只会增加你的复杂度,到头来还是不会用我forEach,所以,函数式编程的思想真的很神奇。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值