JavaScript 手写 forEach 算法实现详解
本文详细介绍如何使用原生 JavaScript 手写实现 forEach 方法。通过解析参数传递、this 指向绑定及异常处理机制,展示完整的底层逻辑。代码包含基础遍历与 thisArg 上下文绑定的两种场景,帮助开发者深入理解数组迭代器的内部工作原理。
JS 手写 forEach 算法实现详解
本文通过具体实例,详细解析了如何在 JavaScript 中手动实现 forEach 算法,旨在为读者提供清晰的参考与学习思路。
手写 forEach
手写 forEach
方法定义与参数说明
forEach() 方法的核心功能是遍历数组中的每一个元素,并对每个元素执行一次指定的回调函数。
arr.forEach(callback(currentValue [, index [, array]])[, thisArg]);
-
callback
- currentValue:表示数组中当前正在被处理的元素值。
- index(可选):表示当前正在处理的元素在数组中的索引位置。
- array(可选):表示调用 方法的那个原始数组对象。
- thisArg(可选):当执行回调函数 callback 时,该参数将作为回调函数内部 this 的值使用。
- 该方法没有返回值,始终返回 undefined。
如果在调用 forEach 时提供了 thisArg 参数,该参数将作为回调函数内部的 this 值。若未提供,则 this 的值为 undefined。在回调函数中,this 的具体绑定行为遵循 JavaScript 通用的 this 绑定规则。
基础遍历示例
let arr = [1, 2, 3, 4];
arr.forEach((...item) => console.log(item));
// [1, 0, Array(4)] 当前值
thisArg 上下文绑定示例
function Counter() {
this.sum = 0;
this.count = 0;
}
// 因为 thisArg 参数(this)传给了 forEach(),每次调用时,它都被传给 callback 函数,作为它的 this 值。
Counter.prototype.add = function(array) {
array.forEach(function(entry) {
this.sum += entry;
++this.count;
}, this);
// ^---- Note
};
const obj = new Counter();
obj.add([2, 5, 9]);
obj.count;
// 3 === (1 + 1 + 1)
obj.sum;
// 16 === (2 + 5 + 9)
- 所有数组实例均继承并拥有此方法。
- 传递给回调函数的参数依次为:当前数组项、当前索引以及原始数组本身。
手写实现源码
Array.prototype.forEach = function(fn, thisArg) {
var _this;
if (typeof fn !== "function") {
throw "参数必须为函数";
}
if (arguments.length > 1) {
_this = thisArg;
}
if (!Array.isArray(arr)) {
throw "只能对数组使用forEach方法";
}
for (let index = 0; index < arr.length; index++) {
fn.call(_this, arr[index], index, arr);
}
};
感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。
更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript数学运算用法总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript数组操作技巧总结》、《JavaScript排序算法总结》、《JavaScript遍历算法与技巧总结》、《JavaScript查找算法技巧总结》及《JavaScript错误与调试技巧总结》
希望本文所述的实现方案对大家掌握 JavaScript 程序设计有所帮助。
JS语法错误会阻止加载吗?区分SyntaxError与资源加载失败
2026-11-05 16:08:46
JavaScript常见SyntaxError语法错误排查与修复方法
2026-11-05 13:58:44
JS中slice、substring和substr截取字符串的区别
2026-11-05 13:43:47
JS 转 TS 手动迁移最佳实践:从配置 tsconfig 到消除 any 类型
2026-11-05 11:53:32
为什么JS数组push后得到的是数字而不是数组?
2026-11-05 09:59:18
