当前位置: 首页 > 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.dtcms.com/a/340377.html

相关文章:

  • CorrectNav——基于VLM构建带“自我纠正飞轮”的VLN:通过视觉输入和语言指令预测导航动作,且从动作和感知层面生成自我修正数据
  • 【Linux】系统部分——磁盘存储结构与文件系统
  • C++八股 —— 设计模式
  • wpf之ComboBox
  • DRF序列化器
  • DeepSeek V3.1 完整评测分析:2025年AI编程新标杆
  • ⭐CVPR2025 给3D高斯穿 “UV 衣” 框架[特殊字符]
  • 路由器NAT的类型测定
  • KubeBlocks AI:AI时代的云原生数据库运维探索
  • Redux 核心概念详解
  • Flutter开发 json_serializable json数据解析
  • 关联规则挖掘2:FP-growth算法(Frequent Pattern Growth,频繁模式增长)
  • rsync + inotify 数据实时同步
  • Android 入门到实战(三):ViewPager及ViewPager2多页面布局
  • 性能测试报告深度解析:从冰冷数据到火热洞察
  • android kernel代码 common-android13-5.15 下载 编译
  • Linux系统:C语言进程间通信信号(Signal)
  • RK3576赋能无人机巡检:多路视频+AI识别引领智能化变革
  • deque的原理与实现(了解即可)
  • 基于截止至 2025 年 6 月 4 日,在 App Store 上进行交易的设备数据统计,iOS/iPadOS 各版本在所有设备中所占比例详情
  • 比剪映更轻量!SolveigMM 视频无损剪切实战体验
  • shell变量进阶
  • 基于51单片机自动浇花1602液晶显示设计
  • Ubuntu-安装Epics Archiver Appliance教程
  • 玳瑁的嵌入式日记D21-08020(数据结构)
  • 服务器内存条不识别及服务器内存位置图
  • 认识Node.js及其与 Nginx 前端项目区别
  • 动手学深度学习(pytorch版):第五章节—多层感知机(1)层和块
  • 从异构计算视角审视ARM与FPGA:架构融合驱动智能时代计算范式革新
  • mybatis xml中表名 字段报红解决