数组方法之forEach底层封装
forEach方法是es5新增的数组方法,用于数组的循环遍历,只有一个参数,需要传入一个函数,很多人说是有三个参数,其实这种说话是错误的,是他的参数函数有三个形参,而不是forEach方法有三个参数。
1. 原生forEach方法的使用
(1)forEach方法接受一个函数参数,该函数参数中有三个形参,当然有些形参用不到就可以不声明。
(2)第一个形参为遍历数组的每一项;第二个形参为遍历数组的索性好;第三个参数为遍历数组的本身
(3)forEach方法可以在所有的数组实例中使用。
下图是forEach的基本使用和执行结果
2.封装思路分析
1.封装的函数应该定义在哪里,要搞明白这个问题之前我得先知道这个函数是给谁用的,当然是给数组用的,但是并不是给单个数组来使用的而是所有数组实例都公用的方法,那什么地方是所有的数组都可以访问到的呢?我们知道一个对象调用方法时假如自身没有定义这个方法,那么就会沿着原型链向上一直查找是否有该方法,没有找到就会报错。所以我们应该定义在数组实例的原型链上,而且是Array的原型对象上,也可以放在Object的原型上但是放在这里的话所有的对象都可以使用,而forEach方法是给数组使用的,所以我们应该定义在数组的原型对象上,即 Array.prototype.myForEach = function () {}
2. 定义好了函数,接下来就是参数的问题,原生forEach方法中接受一个函数类型的参数,所以应该写成 Array.prototype.myForEach = function (callback) {}
3. 原生forEach方法是对数组进行遍历,那我我们调用forEach方法内部肯定是对数组进行循环遍历的操作。那么我们遍历就肯定要知道遍历数组的长度,而我们定义的函数内部怎么拿到需要遍历的数组呢?我们通常的使用方式是 arr.forEach(); 不难看出 forEach函数内部this指向他的调用者,所以在内部函数中可以通过this拿到。
4.首先我们使用forEach方法的时候,有三个形参,而形参是由调用函数传入的实参决定的,所以在函数内部调用传进来的callback,并为其传入三个实参,分别为数组的每一项,数组的索引和数组本身。
优化
从上面我们已经可以实现基本的forEach方法,但是还是会有一些问题,比如使用函数是第一个参数并不是函数类型的,我们该怎么做呢?函数的内部执行出了错误我们该怎么向外界传递错误呢?
1.我们可以对传入进来的callback参数进行数据类型的判断,判断方式在我的第一篇文章就有写到这里就不再过多的说明。
2.可以通过**try{} catch(){}**语法来检测函数内部是否执行出错了并返回错误的原因。
扩充功能
我们可以为自定义的forEach方法增加一个参数,用于筛选循环的数据,比如可以只循环遍历奇数项,或偶数项,或者自定义规则都可以,下面只列举了奇数项和偶数项,自定义的就靠大家去发挥了
关注笨笨的熊