当前位置: 首页 > news >正文

力扣 30 天 JavaScript 挑战 第36天 第8题笔记 深入了解reduce,this

在这里插入图片描述

开始做题

版本一:

/*** @param {Function[]} functions* @return {Function}*/
var compose = function(functions) {return function(x) {let result = x;for(let i=functions.length-1;i>=0;i--){console.log(x);x = functions[i](x);console.log(functions[i]);console.log(x);console.log('--------')}return result;}
};const fn = compose([x => x + 1, x => 2 * x])console.log(fn(4)) 

控制台输出在这里插入图片描述
我也不知道为什么错 问了ai 知道哪里错了 我犯的错太愚蠢了 在for循环里面是对x进行更改 返回的却是result

版本二

/*** @param {Function[]} functions* @return {Function}*/
var compose = function(functions) {return function(x) {let result = x;for(let i=functions.length-1;i>=0;i--){result = functions[i](result);}return result;}
};

这次对了

不理解的地方

  1. 为什么不能输出具体的函数只能输出[Function (anonymous)]在这里插入图片描述解答:
    在js中函数也是一个对象,console.log会输出函数对象,在加上这个函数是匿名函数,所以会输出[Function (anonymous)],如果要是命名函数就会输出[Function: add1]之类的。
    如果要是想输出函数的具体实现,比如x=>x*2之类的,要这样输出 console.log(functions[i].toString());加上toString()
    在这里插入图片描述

学习题解里面的知识点

看题解的时候,发现自己忽略了一种情况就是,当 @param {Function[]} functions为空数组的时候,应该返回原来的x,我写代码的时候,没有考虑这种情况,但是代码却是可以解决这种情况。当 @param {Function[]} functions为空数组的时候,i=functions.length-1 为-1,不符合i>=0,会直接返回本来的x。

方法 1:使用迭代的函数组合

就是我解决这道题的方法。官方的写法明显更优雅,而且使用了两种遍历的方法。

var compose = function (functions) {return function (x) {if (functions.length === 0) return x;let input = x;for (let i = functions.length - 1; i >= 0; i--) {const currFunc = functions[i];input = currFunc(input);}return input;};
};
var compose = function (functions) {return function (x) {if (functions.length === 0) return x;let input = x;for (const func of functions.reverse()) {input = func(input);}return input;};
};

方法二:使用js数组自带方法Array.reduceRight

/*** @param {Function[]} functions* @return {Function}*/
var compose = function(functions) {return function(x) {return functions.reduceRight((taget,fn)=>fn(taget),x)     }
};

之前的题目中对reduce有了更详细的了解,reduceRight跟rudece的使用语法相同,唯一的区别是reduce从左到右累加,reduceRight从右到左累加。reduceRight接受两个参数,一个是函数callbackFn,另一个是初始值initialValue。
函数callbackFn接受四个参数

  1. accumulator
    上一次调用 callbackFn 的结果。在第一次调用时,如果指定了 initialValue 则为指定的值,否则为数组最后一个元素的值。
  2. currentValue
    数组中当前正在处理的元素。
  3. index
    正在处理的元素在数组中的索引。
  4. array
    调用了 reduceRight() 的数组本身。
    上面题目的解法中函数callbackFn就是(taget,fn)=>fn(taget)。其中taget的就是accumulator即累加值,它的初始值为 initialValue。fn就是函数数组中正在被遍历的函数。这个解法中callbackFn没有index,array参数。

方法三:调用第三方库

import { flowRight } from 'lodash';const composedFn = flowRight(...functions);

额外关于this的思考 其实这里我还是不懂

var compose = function(functions) {return function(x) {let result = x;for (let i = functions.length - 1; i >= 0; i--) {result = functions[i](result);}return result;};
};

这里 functionsi 是直接调用函数,所以 调用方式是普通函数调用,那么 this 就会变成 undefined(严格模式) 或 全局对象(非严格模式下的 window/global)。
如果这些函数只是单纯的 x => x + 1 这种纯函数,没问题。
但如果这些函数是对象的方法,依赖 this,就会出错。
下面的函数事对象的方法,依赖 this

const obj = {value: 1,increment: function() { this.value++; return this.value; },double: function() { this.value *= 2; return this.value; },
};

这里 increment 和 double 需要通过 this.value 访问对象里的值。
如果直接 compose:

const badComposedFn = compose([obj.increment, obj.double]);
console.log(badComposedFn(1)); 

执行时 this 已经丢失了(不再指向 obj),所以 this.value 是 undefined,结果就会得到 NaN。
要想在组合时保留原本的 this,就不能直接调用函数,而是要用 .call 或 .apply 来 显式指定调用时的上下文。

const goodCompose = function(functions, context) {return function(x) {let result = x;for (let i = functions.length - 1; i >= 0; i--) {result = functions[i].call(context, result); // 显式绑定 this}return result;};
};

然后使用时传入 obj:

const goodComposedFn = goodCompose([obj.increment, obj.double], obj);
console.log(goodComposedFn(1));  // ✅ 正确输出

这时 this 永远指向 obj,所以函数里访问 this.value 没问题。

http://www.xdnf.cn/news/1335313.html

相关文章:

  • 【嵌入式电机控制#34】FOC:意法电控驱动层源码解析——HALL传感器中断(不在两大中断内,但重要)
  • day075-MySQL数据库服务安装部署与基础服务管理命令
  • 《算法导论》第 35 章-近似算法
  • imx6ull-驱动开发篇31——Linux异步通知
  • 极其简单二叉树遍历JAVA版本
  • 虚拟机部署HDFS集群
  • Redisson最新版本(3.50.0左右)启动时提示Netty的某些类找不到
  • VR交通安全学习机-VR交通普法体验馆方案
  • 从防抖节流到链表树:编程世界中的抽象优化艺术
  • C++智能指针详解:告别内存泄漏,拥抱安全高效
  • Flask高效数据库操作指南
  • C++ MFC/BCG编程:文件对话框(CFileDialog、CFolderPickerDialog)
  • CFBench评测
  • (一)关于步进电机的FOC控制
  • DeepSeek大模型如何重塑AI Agent?从技术突破到行业落地
  • 意象框架:连接感知与认知的统一信息结构分析——基于上古汉语同源词意义系统的词源学与认知语言学探索
  • (认识异常)
  • SED项目复现学习实录
  • JSON::Value 功能详解:从三目运算符到高级用法
  • Git Commit 提交信息标准格式
  • 48 C++ STL模板库17-容器9-关联容器-映射(map)多重映射(multimap)
  • C++进阶-----C++11
  • 【数据结构】线性表——顺序表
  • Linux Shell 常用操作与脚本示例详解
  • CAMEL-Task1-CAMEL环境配置及你的第一个Agent
  • rsync + inotify 数据实时同步
  • 吴恩达 Machine Learning(Class 3)
  • Spring Boot 实战:从项目搭建到部署优化
  • (Python)[特殊字符] 基于Flask/FastAPI的RESTful API服务 + 数据库 + 缓存 + 简单前端 (Python项目)
  • Altium Designer 22使用笔记(8)---PCB电气约束设置