js中数组forEach方法的使用及实现
首先来看下mdn中的介绍
描述
forEach() 方法按升序为数组中含有效值的每一项执行一次 callback 函数,那些已删除或者未初始化的项将被跳过。(说白了就是去循环数组中的元素,每循环一次就调用一次传入的函数。并且在被调用时,不会改变原数组)
语法
arr.forEach(callback(currentValue [, index [, arrSelf]])[, thisArg])
参数描述
callback
为数组中每个元素执行的函数,该函数接收一至三个参数:
(1)currentValue
数组中循环的当前元素。
(2)index 可选
数组中正在处理的当前元素的索引。
(3)arrSelf 可选
当前调用forEach() 方法的数组对象本身。
thisArg 可选
可选参数。当执行回调函数 callback 时,改变回调函数 this 的指向。(如果不传入或者为null,则采用原来的this指向,如果传入则每次调用callback函数时将函数的this指向thisArg参数)
返回值
undefined。
使用
let arrList = [1, 3, 5, 9]
// 不传入thisArg参数时
arrList.forEach(function(currentValue , index, arrSelf) {
console.log(currentValue , index, arrSelf, this)
})
// 打印结果如下
// 1 0 [1, 3, 5, 9] Window
// 3 1 [1, 3, 5, 9] Window
// 5 2 [1, 3, 5, 9] Window
// 9 3 [1, 3, 5, 9] Window
// 传入thisArg参数时
arrList.forEach(function(currentValue , index, arrSelf) {
console.log(currentValue , index, arrSelf, this)
}, {a: 9})
// 打印结果如下
// 1 0 [1, 3, 5, 9] {a: 9}
// 3 1 [1, 3, 5, 9] {a: 9}
// 5 2 [1, 3, 5, 9] {a: 9}
// 9 3 [1, 3, 5, 9] {a: 9}
// 当传入的callback为箭头函数时
arrList.forEach((currentValue , index, arrSelf) => {
console.log(currentValue , index, arrSelf, this)
}, {a: 9})
// 打印结果如下
// 1 0 [1, 3, 5, 9] Window
// 3 1 [1, 3, 5, 9] Window
// 5 2 [1, 3, 5, 9] Window
// 9 3 [1, 3, 5, 9] Window
上述代码演示了forEach方法的使用,打印出了每个传入的参数,注意的是当传入的callback函数为箭头函数时,thisArg参数就不起作用了,是因为箭头函数没有自己的this,并且不可以被改变,此时的this会去向上找它所在作用域的this。下面根据上面描述和使用模拟实现自己的forEach方法:
步骤思路
1、在array原型上添加自己的forEach方法
2、传入所需要的参数
3、使用for循环进行循环数组
4、利用call方法改变回调函数this指向
5、调用回调函数
实现代码
Array.prototype.myForEach = function(callback, thisAry) {
const len = this.length
// 循环数组,利用call方法调用传入的回调函数并改变它的this指向
for (let index = 0; index < len; index++) {
callback.call(thisAry, this[index], index, this)
}
}
测试验证
Array.prototype.myForEach = function(callback, thisAry) {
const len = this.length
// 循环数组,利用call方法调用传入的回调函数并改变它的this指向
for (let index = 0; index < len; index++) {
callback.call(thisAry, this[index], index, this)
}
}
let arrList = [1, 3, 5, 9]
// 不传入thisArg参数时
arrList.myForEach(function(currentValue , index, arrSelf) {
console.log(currentValue , index, arrSelf, this)
})
// 打印结果如下
// 1 0 [1, 3, 5, 9] Window
// 3 1 [1, 3, 5, 9] Window
// 5 2 [1, 3, 5, 9] Window
// 9 3 [1, 3, 5, 9] Window
// 传入thisArg参数时
arrList.myForEach(function(currentValue , index, arrSelf) {
console.log(currentValue , index, arrSelf, this)
}, {a: 9})
// 打印结果如下
// 1 0 [1, 3, 5, 9] {a: 9}
// 3 1 [1, 3, 5, 9] {a: 9}
// 5 2 [1, 3, 5, 9] {a: 9}
// 9 3 [1, 3, 5, 9] {a: 9}
// 当传入的callback为箭头函数时
arrList.myForEach((currentValue , index, arrSelf) => {
console.log(currentValue , index, arrSelf, this)
}, {a: 9})
// 打印结果如下
// 1 0 [1, 3, 5, 9] Window
// 3 1 [1, 3, 5, 9] Window
// 5 2 [1, 3, 5, 9] Window
// 9 3 [1, 3, 5, 9] Window
打印结果和原生方法一致。