【JavaScript】面试手撕柯里化函数

这篇具有很好参考价值的文章主要介绍了【JavaScript】面试手撕柯里化函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


【JavaScript】面试手撕柯里化函数,JavaScript,javascript,面试,开发语言
【JavaScript】面试手撕柯里化函数,JavaScript,javascript,面试,开发语言

🌈个人主页: 鑫宝Code
🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础
💫个人格言: "如无必要,勿增实体"



【JavaScript】面试手撕柯里化函数,JavaScript,javascript,面试,开发语言
【JavaScript】面试手撕柯里化函数,JavaScript,javascript,面试,开发语言

引入

上周我一个学弟,去字节面试实习生。面试官问他有没有用过柯里化,他摇了摇头。

有一说一,确实柯里化在现实中的项目还是用的比较少的。🐶

面试官继续问他是否听说过柯里化,我的老实学弟摇了摇头。半小时面完后,我问学弟面的如何?学弟摇了摇头说,学长,你听说过柯里化吗?

【JavaScript】面试手撕柯里化函数,JavaScript,javascript,面试,开发语言【JavaScript】面试手撕柯里化函数,JavaScript,javascript,面试,开发语言

柯里化

定义

首先,我们参照维基百科给出的定义:

在计算机科学中,柯里化(英语:Currying),又译为卡瑞化加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术

举个🌰

我们正常情况下写sum函数是如下的方式

const sum = function(a,b) {
    return a + b;
}

// 调用
sum(1,2)

但是柯里化后是这样实现的

const sum = function(a) {
  return function(b) {
    return a + b;
  }
}
// 调用
sum(1)(2)

实现

那如果有N个参数呢,以及我要定一个函数能将所有的函数变成柯里化呢?而非仅仅是上面的sum函数

为了解决N个参数的问题,所以我们想到了递归函数。

为了解决将所有的函数变成柯里化,所以我们的入参要加上fn

以下是代码,借鉴了木易杨大佬的代码

function currying(fn, length) {
    // 第一次调用获取函数 fn 参数的长度,后续调用获取 fn 剩余参数的长度
    length = length || fn.length; 	
    // currying 包裹之后返回一个新函数,接收参数为 ...args
    return function (...args) {			
      // 新函数接收的参数长度是否大于等于 fn 剩余参数需要接收的长度
      return args.length >= length	
          ? fn.apply(this, args) // 满足要求,执行 fn 函数,传入新函数的参数
        : currying(fn.bind(this, ...args), length - args.length) 
      // 不满足要求,递归 currying 函数,新的 fn 为 bind 返回的新函数
      //(bind 绑定了 ...args 参数,未执行),新的 length 为 fn 剩余参数的长度
    }
  }
  
  const sum = function(a,b,c){
    return a + b + c;
  }

const currySum = currying(sum);

console.log(currySum(1,2,3));
console.log(currySum(1)(2)(3));
console.log(currySum(1,2)(3));
// 输出都是 6 

快速使用

lodash中的已经带有了curry函数可以使用,使用方式如下:

const sum = function(a, b, c) {
  return a + b + c;
};
 
var currySum = _.curry(abc);
 
console.log(currySum(1,2,3));
console.log(currySum(1)(2)(3));
console.log(currySum(1,2)(3));
// 输出都是 6 

柯里化的作用

感觉柯里化将问题还复杂化了,那柯里化有什么作用呢?

提高自由度

我们可以考虑一个情况,如果对于一个函数,它有3个参数,它的作用是将3个参数相乘返回。如果我突然想乘用2个数的结果呢?是不是使用柯里化就能拿到中间的结果了。

再举个🌰,这个例子借鉴于云中桥大佬

我们工作中会遇到各种需要通过正则检验的需求,比如校验电话号码、校验邮箱、校验身份证号、校验密码等, 这时我们会封装一个通用函数checkByRegExp ,接收两个参数,校验的正则对象和待校验的字符串。

function checkByRegExp(regExp,string) {
    return regExp.test(string);  
}

checkByRegExp(/^1\d{10}$/, '123456789'); // 校验电话号码
checkByRegExp(/^1\d{10}$/, '1234567810'); // 校验电话号码
checkByRegExp(/^(\w)+(.\w+)*@(\w)+((.\w+)+)$/, 'test@163.com'); // 校验邮箱
checkByRegExp(/^(\w)+(.\w+)*@(\w)+((.\w+)+)$/, 'test@qq.com'); // 校验邮箱

然而当要校验的值非常多时,我们前面的正则表达式要一直写着,这会导致代码不美观,我们可以借助柯里化对checkByRegExp进行封装,以简化代码书写,提高代码可读性。

//进行柯里化
let _check = curry(checkByRegExp);
//生成工具函数,验证电话号码
let checkCellPhone = _check(/^1\d{10}$/);
//生成工具函数,验证邮箱
let checkEmail = _check(/^(\w)+(.\w+)*@(\w)+((.\w+)+)$/);

checkCellPhone('123456789'); // 校验电话号码
checkEmail('test@163.com'); // 校验电话号码
bind函数

其实bind函数也算是提高自由度的例子,不过由于它是官网的函数,所以单独讲下。

这块借鉴于木易杨大佬的文章,在此感谢🙏。

我们先看一下bind的例子

const obj = {
  name: "小明",
};

const fn = function () {
  console.log(this.name);
}.bind(obj);

这里 bind 用来改变函数执行时候的上下文,但是函数本身并不执行,所以本质上是延迟计算,提高函数的自由度。

我们可以查看一下bind的简单实现,返回了函数,本身也算是一种柯里化吧。

// 简化实现,完整版实现中的第 2 步
Function.prototype.bind = function (context) {
    var self = this;
    // 第 1 个参数是指定的 this,截取保存第 1 个之后的参数
		// arr.slice(begin); 即 [begin, end]
    var args = Array.prototype.slice.call(arguments, 1); 

    return function () {
        // 此时的 arguments 是指 bind 返回的函数调用时接收的参数
        // 即 return function 的参数,和上面那个不同
      	// 类数组转成数组
        var bindArgs = Array.prototype.slice.call(arguments);
      	// 执行函数
        return self.apply( context, args.concat(bindArgs) );
    }
}

参考资料

「前端进阶」彻底弄懂函数柯里化

深入高阶函数应用之柯里化
【JavaScript】面试手撕柯里化函数,JavaScript,javascript,面试,开发语言

【JavaScript】面试手撕柯里化函数,JavaScript,javascript,面试,开发语言文章来源地址https://www.toymoban.com/news/detail-840416.html

到了这里,关于【JavaScript】面试手撕柯里化函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【JavaScript】手撕前端面试题:手写Object.create | 手写Function.call | 手写Function.bind

    🖥️ NodeJS专栏:Node.js从入门到精通 🖥️ 博主的前端之路(源创征文一等奖作品):前端之行,任重道远(来自大三学长的万字自述) 🖥️ TypeScript知识总结:TypeScript从入门到精通(十万字超详细知识点总结) 🧑‍💼个人简介:大三学生,一个不甘平庸的平凡人🍬 👉

    2024年02月21日
    浏览(44)
  • 手撕前端面试题【javascript~ 总成绩排名、子字符串频次统计、继承、判断斐波那契数组等】

    html页面的骨架,相当于人的骨头,只有骨头是不是看着有点瘆人,只有HTML也是如此。 css,相当于把骨架修饰起来,相当于人的皮肉。 js(javascripts),动起来,相当于人的血液,大脑等一切能使人动起来的器官或者其他的。 在刷题之前先介绍一下牛客。Leetcode有的刷题牛客都有,

    2024年01月15日
    浏览(34)
  • 开发语言漫谈-JavaScript

           JavaScript、Java名字很相近,但它们没有任何亲缘关系,是由不同公司开发的编程语言。Java由Sun公司(后被Oracle收购)开发,JavaScript最初是由Netscape公司开发的(当年浏览器的霸主)。JavaScript最初的名字是 LiveScript,Netscape将其命名为 JavaScript,无非是蹭 Java流量。当

    2024年04月16日
    浏览(37)
  • 30个前端开发中常用的JavaScript函数

    🧑‍💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 在前端开发中通常会用到校验函数,检验是否为空、手机号格式、身份证格式等等。现按照用途分类整理出了30个常用的方法,在V

    2024年02月14日
    浏览(34)
  • 建站系列(五)--- 前端开发语言之HTML、CSS、JavaScript

    建站系列(一)— 网站基本常识 建站系列(二)— 域名、IP地址、URL、端口详解 建站系列(三)— 网络协议 建站系列(四)— Web服务器之Apache、Nginx 建站系列(五)— 前端开发语言之HTML、CSS、JavaScript 建站系列(六)— 后端开发语言 建站系列(七)— 常用前后端框架

    2024年02月09日
    浏览(40)
  • (自己动手开发自己的语言练手级应用)JSON(JavaScript Object Notation) 产生式(BNF)

     写自己的开发语言时,很多人都会拿JSON当第一个练习对象 开源net json FJSON 解析工具 https://dbrwe.blog.csdn.net/article/details/107611540?spm=1001.2014.3001.5502 以上是JSON的简化产生式表示形式。其中, json 是最顶层的规则,可以是一个对象或一个数组。 object 表示一个对象,由一对大括号

    2024年02月10日
    浏览(36)
  • 大型医院云HIS系统:采用前后端分离架构,前端由Angular语言、JavaScript开发;后端使用Java语言开发 融合B/S版电子病历系统

    一套医院云his系统源码 采用前后端分离架构,前端由Angular语言、JavaScript开发;后端使用Java语言开发。融合B/S版电子病历系统,支持电子病历四级,HIS与电子病历系统均拥有自主知识产权。 文末卡片获取联系! 基于云计算技术的B/S架构的医院管理系统(简称云HIS),采用前后

    2024年02月03日
    浏览(35)
  • 细说JavaScript函数(JavaScript函数详解)

    函数的作用就是封装一段JavaScript代码,让开发者可以通古简单的方式使用这段代码 一、函数的分类 在几乎所有的编程语言中,都有函数这一概念,并且没中语言本身都继承了丰富的函数,这类函数被称为系统函数或者内置函数,系统函数在语言设计时就已经定义好了,开发

    2024年02月01日
    浏览(33)
  • JavaScript【四】JavaScript中的函数

    哈喽小伙伴们,本文将收录在JavaScript【前端童子功】这个专栏里;这个专栏里边会收录一些JavaScript的基础知识和项目实战;希望大家可以多多支持,你们的支持就是我创作的动力;让我们一起来看看吧🤘 函数 :将完成某一特定功能的代码封装起来,并且可以重复调用的代

    2023年04月21日
    浏览(37)
  • JavaScript经典教程(七)-- JavaScript基础 -- 函数、argument、匿名函数、函数深入、选项卡

    1、函数 (1)特性 1、每个函数都有自己的作用域。 2、如果执行该变量名,会返回自己,即返回函数本身。 3、正常调用,返回函数中的执行结果。 当函数中无执行内容时,返回默认return=undefind;(每个函数都有默认return=undefined) 当函数中有执行内容时,返回返回值。 4、re

    2024年02月02日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包