【一天时间|JavaScript进阶】函数式编程高阶函数的应用
一天时间系列文章是博主精心整理的面试热点问题和难点问题,吸收了大量的技术博客与面试文章,总结多年的面试经历,带你快速并高效地审视前端面试知识。直击技术痛点,主动出击,精密打击,这才是面试拿到高薪的秘诀!
- 本系列订阅 一天时间迅速准备前端面试(高薪精品)–欢迎订阅
目录
- 前言
- 函数是 JavaScript 的一等公民
- 纯函数
- 纯函数的好处 memoize
- 柯里化 Curry
- 高阶函数
- 高阶函数的应用
- 参考
前言
函数是 JavaScript 的一等公民
简单提一下,一等公民都具备以下特性:
- 可以被存入变量或者其他数据结构
- 可以作为函数的参数
- 可以作为函数的返回值
- 可以判断相等性
写过JS的人肯定都知道函数是能满足上述的特性。
函数式编程是一种编程范式,其中函数定义的是表达式树,每个表达式都返回一个值,而不是改变程序状态的命令语句。因为函数是 JavaScript 的一等公民,所以可以把函数作为其他函数的参数或者返回值,这样就可以将其中小功能以模块化的方式组合在一起。
纯函数
可以通过禁止更改外部状态和数据来定义纯函数,纯函数是只依赖实际参数,不管任何全局或者局部的状态。即输入相同的参数,输出的内容永远都是一样的。
const sum = (x, y) => x + y;
sum(1, 2) // 3
原生例子
let arr = [1, 2, 3];
arr.slice(0,1); // [1]
arr.slice(0,1); // [1]
arr // [1, 2, 3]arr.splice(0,1); // [1]
arr.splice(0,1); // [2]
arr // [3]
由上可见数组的 slice
方法是纯函数,不会改变原对象;splice
改变了原对象,导致每次操作自身都发生变化,所以不是纯函数。
纯函数的好处 memoize
使用纯函数时我们发现程序出现了与预期不符的情况,也就是输出的值不是想要得值,那么只用检查输入的参数就OK。
上面提到纯函数,输入值不变,那么输出值也会不变,这里就可以对比输入的参数是否发生变化,来决定是否要重新渲染来实现一个缓存优化。
const memoize = f => { // 缓存函数let cache = {};return a => { // 这里为了方便 就只接收一个参数了const prevValue = cache[a];if (prevValue) {console.log(`cache ${prevValue}`);return prevValue;}return cache[a] = f(a); // 缓存纯函数的值}
}
const double = x => x * 2; // 运算函数(纯函数)
const f = memoize(double);f(2); // 4
f(2); // cache 4f(8); // 16
f(8); // cache 16
柯里化 Curry
柯里化是把接收多个参数的函数变成接收单一参数的函数,剩下的参数再通过返回的函数来进行接收。 简单理解就是把函数拆的更细,返回的函数依赖第一个参数进行计算,可以缩小适用范围,创建一个针对性更强的函数。
可以将上述求和纯函数改成下面的写法
const sum = x => y => x + y;
sum(1)(2); // 3
将 sum
函数转为只接收一个参数,并返回一个函数,再次调用将得到结果。 或许有人觉得这样写纯属蛋疼,那么就举一个业务中会用到的一个例子。我们需要一个可以将金额转为千分位的函数,但是金额的单位不定,有可能是分,有可能是角等。
const formatMoney = (money, step) => {let str = (money / step).toFixed(2); // 两位小数const index = str.indexOf('.');if (index > 3) {const start = str.substring(0, index).replace(/\B(?=(?:\d{3})+$)/g, ','); // 增加千分位符号return start + str.substring(index);};return str;
}
formatMoney(1000000, 100); // 分 10,000.00
formatMoney(123456, 100); // 分 1,234.56
formatMoney(123456, 10); // 角 12,345.60
传入两个参数(money, step)
金额和单位,在函数中依据单位来实时金额。但是每次都要传单位,造成重复的代码。
我们可以将上述方法转为柯里化函数:
const formatMoney = step => money => {let str = (money / step).toFixed(2); // 两位小数const index = str.indexOf('.');if (index > 3) {const start = str.substring(0, index).replace(/\B(?=(?:\d{3})+$)/g, ','); // 增加千分位符号return start + str.substring(index);};return str;
}
const pennyMoney = formatMoney(100); // 单位是分
pennyMoney(1000000); // 10,000.00
pennyMoney(123456); // 1,234.56const dimeMoney = formatMoney(10); // 单位是角
dimeMoney(1000000); // 100,000.00
dimeMoney(123456); // 12,345.60formatMoney(1)(1000000); // 1,000,000; // 元
我们通过柯里化的方式预先传入单位,返回一个针对该单位的格式化方法,这样我们就能在不同的情况下加以复用,其中 pennyMoney
与 dimeMoney
也能加以复用,不用在每次都传入要通过什么单位来格式化。
高阶函数
高阶函数可以把其他函数作为参数输入或者作为其返回值输出。
原生的方法有很多都是高阶函数,例如 Array.prototype.map
方法,他接收一回调函数,从回调函数中获取返回值,再使用这些值创建一个新的数组并返回。
高阶函数的应用
上述我们通过柯里化的方式优化了格式金额的方法,可以看到柯里化的方式也会返回一个函数,那么我们可以认为,他也是高阶函数。下面我们将再自定义一些高阶函数,让我们更加理解高阶函数的应用。
【一天时间|JavaScript进阶】函数式编程高阶函数的应用相关推荐
- python学习——函数式编程——高阶函数
python学习--函数式编程--高阶函数 函数式编程(高阶函数):1:map && reduce; 2 : filter; 3: sorted; ------------------ ...
- Python进阶:函数式编程(高阶函数,map,reduce,filter,sorted,返回函数,匿名函数,偏函数)...啊啊啊...
函数式编程 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计 ...
- python3_函数_形参调用方式 / 不定长参数 / 函数返回值 / 变量作用域 / 匿名函数 / 递归调用 / 函数式编程 / 高阶函数 / gobal和nonlocal关键字 / 内置函数
1.形参的调用方式 1. 位置参数调用 2. 关键词参数调用 原则: 关键词参数调用不能写在位置参数调用的前边 def test1(name, age):print("name:" ...
- 函数式编程 --- 高阶函数
含义: 高阶函数全称 (Higher-order function) 1.可以把函数作为参数传递给另一个函数 2.可以把函数作为另一个函数的返回结果 意义:高阶函数是用来抽象通用的问题:抽象可以帮我们 ...
- JavaScript 面向对象编程(三) —— 函数进阶 / 严格模式 / 高阶函数 / 闭包 / 浅拷贝和深拷贝
本篇为 JavaScript 进阶 ES6 系列笔记第三篇,将陆续更新后续内容.参考:JavaScript 进阶面向对象 ES6 :ECMAScript 6 入门 系列笔记: JavaScript 面 ...
- 函数式编程4-高阶函数
以其他函数作为参数的函数 本章的所有代码,均在github.com/antgod/func- 关于传递函数的思考 max 在很多编程语言的核心库,都包含一个叫做max的函数.包括underscore也 ...
- Python编程 高阶函数使用技巧
在坚持的初期,坚持本身比坚持的事情更重要.也许,生活的意义并不在于实现了怎样伟大的梦想,而是在于自己全身心地投入,让每一天都成为梦想的一部分.只要是能确定带给自己价值感的事情,去做就好.时间在流逝,每 ...
- Python学习札记(二十) 函数式编程1 介绍 高阶函数介绍
参考: 函数式编程 高阶函数 Note A.函数式编程(Functional Programming)介绍 1.函数是Python内建支持的一种封装,我们通过一层一层的函数调用把复杂任务分解成简单的任 ...
- python order函数_Python进阶内容(一)--- 高阶函数 High order function
0. 问题 # 本文将围绕这段代码进行Python中高阶函数相关内容的讲解 # 文中所有代码的兼容性要求为:Python 3.6,IPython 6.1.0 def addspam(fn): def ...
最新文章
- git 修改仓库的描述_git简介、基本命令和仓库操作
- 爱奇艺蒙版AI:弹幕穿人过,爱豆心中坐
- eclipse常用设置之自动格式化
- 为什么要用webUI?
- excel删除空行_Excel里99.9%的人都踩过的坑,早看早避开!
- 可以买的一本书:3D计算机图形学(原书第3版)
- 2020年,中国AI创业公司将走向何方
- 左右黑白极简滚动个人主页模板
- sql中聚合函数和分组函数_SQL选择计数聚合函数-语法示例解释
- Facebook再遭黑客攻击 部分账户密码被盗
- php 打印系统变量值,php – Twig:打印变量名为String的变量的值
- 毕业设计 基于STM32停车管理系统 - 物联网
- 史上最全 | 编程入门指南
- 移动端人脸识别活体检测,高效集成
- YOLOv3 SPP源码分析
- 【Python爬虫Scrapy框架】一、Scrapy爬虫框架的入门案例
- 数据库查询-分数排名
- 使用busybox制作rootfs
- linux lpte_PC并行口LPT的IO操作(基于WinIo)
- HTML静态网页作业——基于html+css+javascript+jquery+bootstarp响应式成都家乡介绍网页
热门文章
- android请输入姓名代码,Android获取联系人姓名和电话代码
- 高中毕业从汽修转行自学Python,月薪翻了三倍,我有一份转行秘籍分享给你
- 我们是如何在研发过程中控制质量的?产品质量正变得越来越重要
- CHITUBOX Pro 1.2.0
- 闲暇之余的WiFi生活
- 汽车可视化市场现状研究分析报告-
- Command line is too long. Shorten command line for test.ttt or also for JUnit default configuration?
- 给你一张百万级数据的表,如何做到查询优化?
- 畅视业务订单子表查询
- 2011考研复试经历与总结