能否在JavaScript的reduce迭代中调用外部函数?实现方法解析
在reduce迭代中调用外部函数的可行性与正确实现
当然可以在reduce的迭代过程中调用外部函数/方法,这种做法完全合理且可行,在日常业务开发中是很常见的操作——比如你这里的日期格式化场景,把通用逻辑抽成独立的工具函数,能让代码更清晰、更易维护。
不过你的示例代码里存在一个小问题:this的指向不正确,会导致调用this.formatDate时出现错误。下面我来帮你分析并给出正确的实现方式:
问题分析
你在reduce里使用了普通函数作为回调:
myArray.reduce(function (res, value) { // ... res[v_key] = { firstVar: value.firstVar, NbrKo: 0, sndVar: this.formatDate(value.sndVar) }; // ... }, {});
普通函数作为reduce回调时,它内部的this默认不会指向类的实例(非严格模式下指向全局对象,严格模式下是undefined),而你的formatDate是类的实例方法,所以这里会出现this.formatDate is not a function的报错。
正确实现方式
有两种简单的方式可以解决这个this绑定问题:
方式一:将reduce回调改为箭头函数
箭头函数不会创建自己的this,它会继承外层作用域(也就是mainFunction)的this,这样就能正确访问到类实例的formatDate方法:
private mainFunction() { let v_arrayGroup:string[] = []; myArray.reduce((res, value) => { // 改成箭头函数 let v_key = value.firstVar; if (!res[v_key]) { // 这里的this指向类实例,能正确调用formatDate res[v_key] = { firstVar: value.firstVar, NbrKo: 0, sndVar: this.formatDate(value.sndVar) }; v_arrayGroup.push(res[v_key]); } res[v_key].NbrKo++; return res; }, {}); this.v_finalArray = v_arrayGroup; // 假设v_finalArray是类属性,建议加上this } private formatDate = (p_date:Date) => { let addZeroToLoneFigure = (n) => n.toString().length === 1 ? '0' + n : n.toString(); let _dateReturn = 'DD/MM/YYYY'; _dateReturn = _dateReturn.replace("DD", addZeroToLoneFigure(p_date.getDate())); _dateReturn = _dateReturn.replace("MM", addZeroToLoneFigure(p_date.getMonth() + 1)); _dateReturn = _dateReturn.replace("YYYY", addZeroToLoneFigure(p_date.getFullYear())); return _dateReturn; }
方式二:指定reduce的thisArg参数
reduce方法本身支持第三个参数thisArg,可以用来指定回调函数内部this的指向,直接传入类实例this即可:
private mainFunction() { let v_arrayGroup:string[] = []; myArray.reduce(function (res, value) { let v_key = value.firstVar; if (!res[v_key]) { res[v_key] = { firstVar: value.firstVar, NbrKo: 0, sndVar: this.formatDate(value.sndVar) }; v_arrayGroup.push(res[v_key]); } res[v_key].NbrKo++; return res; }, {}, this); // 第三个参数传入this,指定回调的this指向类实例 this.v_finalArray = v_arrayGroup; } private formatDate = (p_date:Date) => { // 保持原代码不变 let addZeroToLoneFigure = (n) => n.toString().length === 1 ? '0' + n : n.toString(); let _dateReturn = 'DD/MM/YYYY'; _dateReturn = _dateReturn.replace("DD", addZeroToLoneFigure(p_date.getDate())); _dateReturn = _dateReturn.replace("MM", addZeroToLoneFigure(p_date.getMonth() + 1)); _dateReturn = _dateReturn.replace("YYYY", addZeroToLoneFigure(p_date.getFullYear())); return _dateReturn; }
总结
- 在
reduce迭代中调用外部函数是完全合理的,能有效拆分复杂逻辑,提升代码可读性和复用性; - 核心注意点是回调函数的
this绑定问题,通过箭头函数或reduce的thisArg参数就能轻松解决; - 你的
formatDate用箭头函数定义是很合适的,它已经绑定了类实例的this,只要回调里的this正确指向实例,就能正常调用。
内容的提问来源于stack exchange,提问作者oox-hmz




