面试高频考点——手写compose

引言

在 JavaScript 中,函数是一等公民,这意味着函数可以作为参数传递,也可以作为返回值返回。这种特性使得 JavaScript 非常适合函数式编程(Functional Programming,FP)。函数式编程中的一个重要概念是函数组合(Function Composition),它允许我们将多个函数组合成一个新的函数,从而实现更复杂的功能。

在面试中,手写compose函数是一个常考点,本文将深入探讨这个问题。

高阶函数

高阶函数(Higher-Order Function)是指那些接受一个或多个函数作为输入参数的函数,或者返回一个函数作为结果的函数。这两种情况都可以单独出现,也可以同时出现在一个高阶函数中。

高阶函数是函数式编程的核心概念之一,它使得我们可以将函数抽象出来,实现更灵活的代码设计。

函数组合

题目要求:将以下函数封装成一个函数,实现大写并拼接的功能

javascript 复制代码
// 字符大写
var toUpperCase = function(x) {
  return x.toUpperCase();
};
// 小写
var toLowerCase = function(x) {
  return x.toLowerCase();
}
// 字符拼接
var hello = function(x) {
  return 'HELLO, ' + x;
};

初步实现

js 复制代码
var greet = function(x){
  return hello(toUpperCase(x))
} 
var greet2 = function(x){
  return hello(toLowerCase(x)) 
}
console.log(greet('zhang'),greet('ZHANG')) // ZHANG  zhang

我们很快就能想到答案,结果也完全没有问题。但这或许是许多初学者,或代码经验不丰富的程序员常见的问题。

但这有很多问题:几个函数之间耦合性太高,如果toUpperCasetoLowerCase或是hello函数被修改添加新的功能之后,greet的结果就可能发生错误,也要同时进行修改。我们针对这一问题,对代码进行完善。

进阶,降低耦合性

javascript 复制代码
var compose = function(f, g) {
  return function(x) {
    return f(g(x));
  };
};
var greet = compose(hello, toUpperCase);
console.log(greet('zhang'));   // ZHANG

这个 compose 函数接受两个函数 fg,并返回一个新的函数。新函数会先调用 g(x),然后将结果传递给 f

这样,我们想要使用那个函数就传入哪个函数进行使用。并且降低了各个函数之间的依赖性。

但是,我们可以把函数变得更为完美一些,可以允许传入任意个参数。

最终的compose,支持多个函数的组合

手写 compose 函数是面试中的一个高频考点。你需要掌握以下几点:

  • 如何接受多个函数作为参数(es6 剩余参数... 或是 arguments)。
  • 如何从右到左依次调用这些函数(args.length - 1)。
  • 如何使用闭包保存参数列表(外部函数返回了一个内部函数,该内部函数能够访问外部函数的变量)。
javascript 复制代码
var compose = function(...args) {  // es6 剩余参数
  // var args = arguments;  // 类数组 拿到所有参数
  var start = args.length - 1;  // 最右边的函数
  return function(x) {
    var i = start;
    var result = args[start].call(this, x); // 本例中只有一个参数,就先使用call了  
    while(i--) {
      result = args[i].call(this, result);
    } 
    return result;
  }
}

总结

函数组合是函数式编程中的一个重要概念,它允许我们将多个函数组合成一个新的函数,从而实现更复杂的功能。在面试中,高阶函数、闭包、函数组合的实现及其应用场景是常见的考点。

相关推荐
子兮曰2 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰2 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万2 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝2 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋2 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
晨米酱2 天前
AGENTS.md:Agent 的上下文策略层
面试·架构·agent
卡布鲁2 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄2 天前
JavaScript 隐式全局变量解析
javascript
彧azz2 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
汉堡大王95272 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端