自定义实现forEach时如何检测回调函数可接收的参数数量
自定义myForEach方法的实现方案
现有代码的核心问题
- 原型方法误用箭头函数:箭头函数没有独立的
this绑定,定义在Array.prototype上时this会指向外层全局上下文,无法指向调用方法的数组实例,需要改为普通函数声明。 - 回调参数数量检测逻辑错误:
callback.arguments是函数执行时的实参集合,未执行时无法读取,要获取回调声明的形参数量应该使用Function实例自带的length属性。
修正后的代码实现
Array.prototype.myForEach = function(callback) { if(typeof callback !== 'function') { throw new Error("Callback for myForEach is not a function") } // 获取回调声明的形参数量 const paramCount = callback.length for(let i = 0; i < this.length; i++) { // 按形参数量传递对应参数 switch(paramCount) { case 1: callback(this[i]) break case 2: callback(this[i], i) break case 3: default: // 形参≥3个时和原生逻辑对齐,固定传三个参数 callback(this[i], i, this) } } }
效果验证
你可以用以下测试用例验证效果:
const arr = [10, 20, 30] // 仅接收元素参数 arr.myForEach(item => console.log(item)) // 输出:10、20、30 // 接收元素+索引参数 arr.myForEach((item, index) => console.log(item, index)) // 输出:10 0、20 1、30 2 // 接收元素+索引+原数组参数 arr.myForEach((item, index, originArr) => console.log(item, index, originArr === arr)) // 输出:10 0 true、20 1 true、30 2 true
补充说明
原生
Array.prototype.forEach的实现并不会判断回调的形参数量,每次调用回调时都会固定传入三个参数,回调可以按需接收、忽略不需要的参数,不存在性能损耗。如果你需要和原生逻辑完全对齐,可以删除参数数量判断的分支,直接调用callback(this[i], i, this)即可。
内容的提问来源于stack exchange,提问作者Meta Xenology
相关产品推荐
相关产品推荐

