高阶函数的定义

在《javascript设计模式和开发实践》中是这样定义的。

  • 函数可以作为参数被传递;
  • 函数可以作为返回值输出。

结合这两个特点,首先想到的肯定是回调函数,回调函数也是高阶函数的一种,除了回调函数,还有很多的高阶函数,这篇文章主要是惰性函数、柯里化函数、compose函数这三种。

一、惰性函数

概念

懒,执行过一遍的东西,如果第二遍执行还是一样的效果,则我们就不想让其重复执行第二遍了

栗子

我们要封装一个获取元素属性的方法,因为低版本的ie浏览器不支持getComputedStyle方法,做了一个容错处理

function getCss(element, attr) {if ('getComputedStyle' in window) {return window.getComputedStyle(element)[attr];}return element.currentStyle[attr];
}

但是每次进这个方法都要做一下判断,为了提高性能,我们可以存一个变量,然后每次进去判断变量就好了

var flag = 'getComputedStyle' in window
function getCss(element, attr) {if (flag) {return window.getComputedStyle(element)[attr];}return element.currentStyle[attr];
}

这样每一次还是需要判断,有没有更好的方法呢?惰性函数的思想就可以完美解决这个问题

function getCss(element, attr) {if ('getComputedStyle' in window) {getCss = function (element, attr) {return window.getComputedStyle(element)[attr];};} else {getCss = function (element, attr) {return element.currentStyle[attr];};}// 为了第一次也能拿到值return getCss(element, attr);
}getCss(document.body, 'margin');
getCss(document.body, 'padding');
getCss(document.body, 'width');

第一次执行,如果有getComputedStyle这个方法,getCss就被赋值成

function (element, attr) {return window.getComputedStyle(element)[attr];
};

而后的每一次就会执行上面这个函数,否则则相反

总结

惰性载入函数有两个主要优点,

  • 1、是显而易见的效率问题,虽然在第一次执行的时候函数会意味赋值而执行的慢一些,但是后续的调用会因为避免的重复检测更快;
  • 2、是要执行的适当代码只有当实际调用函数是才执行,很多JavaScript库在在加载的时候就根据浏览器不同而执行很多分支,把所有东西实现设置好,而惰性载入函数将计算延迟,不影响初始脚本的执行时间。

二、函数柯理化

定义

利用闭包保存机制,把一些信息预先存储下来(预处理的思想)

function fn() {}
let res = fn(1, 2)(3);
console.log(res); //=>6  1+2+3

封装一个方法,调用以后求出和(两次执行的传参个数都不固定)

解题思路:

函数第二次执行,第一个函数的返回值一定是一个函数,第二个函数的返回值应该是求和的数值function fn(...outerArgs) {return function anonymous(...innerArgs) {// args:外层和里层函数传递的所有值都合并在一起let args = outerArgs.concat(innerArgs);return args.reduce((n, item) => n + item);};
}

第二个函数使用了第一个函数的值,所以函数1不会被释放,利用闭包的保护机制,将值预先保存起来

三、compose函数

定义

组合函数,把多层函数嵌套调用扁平化

栗子

下面四个方法,每种方法都会把参数0进行处理,给x传一个值如果要得出四种方法以后的和:

const fn1 = (x, y) => x + y + 10;
const fn2 = x => x - 10;
const fn3 = x => x * 10;
const fn4 = x => x / 10;let res = fn4(fn2(fn3(fn1(20))));
let res1 = compose(fn1, fn3, fn2, fn4)(20, 30);

res得出的值,可以实现这个需求,但是需要函数套函数,现在可以定义一个compose函数,使得res和res1的值相等,将函数实现扁平化

function compose(...funcs) {// FUNCS:存储按照顺序执行的函数(数组) =>[fn1, fn3, fn2, fn4]return function anonymous(...args) {// ARGS:存储第一个函数执行需要传递的实参信息(数组)  =>[20]if (funcs.length === 0) return args;if (funcs.length === 1) return funcs[0](...args);return funcs.reduce((N, func) => {// 第一次N的值:第一个函数执行的实参  func是第一个函数// 第二次N的值:上一次func执行的返回值,作为实参传递给下一个函数执行return Array.isArray(N) ? func(...N) : func(N);}, args);};
}

完美实现compose函数,不用再函数套函数

react中的redux源码中的compose函数用的是另外思想实现的

四、单例设计模式

定义

var obj1 = {name: 'wanghuahua'
}
var obj2 = {name: 'jerry'
}
console.log(obj1.name)
console.log(obj2.name)

上面的两个obj就是最基础的单例

单例模式就是:用单独的实例来管理当前事物的相关特征[属性和方法](类似于实现一个分组的特点)

而此时obj1/obj2不仅仅叫做一个对象,也被成为命名空间

特点

  • 类只有一个实例
  • 全局可访问该实例
  • 自行实例化(主动实例化)
  • 可推迟初始化,即延迟执行(与静态类/对象的区别)

虽然全局变量可以实现单例,但因其自身的问题,不建议在实际项目中将其作为单例模式的应用,特别是中大型项目的应用中,全局变量的维护该是考虑的成本。

高级单例设计模式

基于闭包管控的单例模式称为:高级单例设计模式,以此来实现模块划分(最早的模块化思想)

let wanghuahua = (function () {function query() {}function tools() {}return {name: 'AREA',tools};
})();
wanghuahua.tools();let jerry = (function () {function fn() {meimei.getXxx();}function query() {}return {query}
})();let meimei = (function () {function fn() {}function getXxx() {}jerry.query();return {getXxx}
})();
// 每个模块都可以有自己私有的方法,想要暴露给全局的就return出去// es6的export已经不需要这么写了公众号:

export function函数传参_04 js高阶函数(惰性函数、柯里化函数、compose函数)和单例设计模式...相关推荐

  1. JavaScript函数式编程(纯函数、柯里化以及组合函数)

    JavaScript函数式编程(纯函数.柯里化以及组合函数) 目录 JavaScript函数式编程(纯函数.柯里化以及组合函数) 前言 1.纯函数 1.1.纯函数的概念 1.2.副作用 1.3.纯函数 ...

  2. 纯函数、柯里化、组合函数的解析以及代码实现

    文章目录 一.纯函数的概念和理解 二.JavaScript柯里化 1.柯里化的理解 2.将函数柯里化的代码实现 三.组合函数 1.组合函数的理解 2.通用的组合函数的实现 一.纯函数的概念和理解 纯函 ...

  3. export function函数传参_从底层看前端(七)—— JavaScript到底有多少种函数?

    在上篇文章中我们了解到了执行上下文是什么,也知道了任何语句的执行都会依赖特定的上下文. 一旦上下文被切换,整个语句的效果可能都会发生变化.那么,切换上下文的时机就显得非常重要. 在JavaScript ...

  4. js 高阶函数之柯里化

    博客地址:https://ainyi.com/74 定义 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且 ...

  5. 了解js基础知识中的作用域和闭包以及闭包的一些应用场景,浅析函数柯里化

    js基础知识中的作用域和闭包 一.作用域 1.作用域.自由变量简介 (1)作用域定义 (2)作用域实例演示 (3)自由变量定义 (4)自由变量实例演示 2.作用域链简介 (1)作用域链定义 (2)作用 ...

  6. 16、react 中的高阶函数和柯里化

    react 中的高阶函数和柯里化 这一篇博文我们说一下 高阶函数 和 柯里化,这两个次可能第一次听说,不知道是啥意思,我们先不管他哈,记得上一篇博客,我们实现了一个登陆的案例是吧?输入用户名和密码,点 ...

  7. JS函数curry(柯里化)

    原文地址:http://blog.jobbole.com/77956/ 什么是柯里化? 柯里化是这样的一个转换过程,把接受多个参数的函数变换成接受一个单一参数(译注:最初函数的第一个参数)的函数,如果 ...

  8. Scala 高阶函数(作为值的函数、匿名函数、闭包、柯里化)+隐式转换和隐式参数...

    Scala高级特性 1.    学习目标 1.1.   目标一:深入理解高阶函数 1.2.   目标二:深入理解隐式转换 2.    高阶函数 2.1.   概念 Scala混合了面向对象和函数式的特 ...

  9. JS高级——纯函数、柯里化(手写自动柯里化函数)、组合函数(手写自动组合函数)

    一.理解JavaScript纯函数 函数式编程中有一个非常重要的概念叫纯函数,JavaScript符合函数式编程的范式,所以也有纯函数的概念: 在react开发中纯函数是被多次提及的: 比如react ...

最新文章

  1. PgSQL · 实战经验 · 如何预测Freeze IO风暴
  2. Java - HtmlEmail 邮件发送
  3. Arch Linux 没有声音:Intel sound card snd_hda_intel not working 解决方法
  4. SAP ABAP SteammPunk 蒸汽朋克的最新进展 - 嵌入式蒸汽朋克
  5. iOS 10 升级后无法真机测试 Could not find Developer Disk Image
  6. YUI经验谈 - 自定义事件默认行为
  7. 迪捷软件团队研发的国产替代MBSE系统建模仿真软件
  8. java飞机大战分数累加代码_JAVA 基础编程练习题39 【程序 39 分数累加】
  9. 数据结构:邻接表法存储有向图
  10. 新媒体推广:一篇文章学会全平台信息流优化 !你get到了吗? | 黎想
  11. 如何发送电子邮件到别人邮箱?
  12. 《宗教与科学》——罗素 读书笔记
  13. github 发布静态页面
  14. 搜索引擎代码资源[转载]
  15. c语言中要让音乐暂停还用什么指令,【Android】Broadcast控制音乐暂停继续等
  16. creo 二次开发 protookit 官方make file 案例试运行
  17. Codeforces Round #670 (Div. 2) C D E
  18. 精彩东博会丨我委会员单位联通沃音乐打卡第五届中国—东盟信息港论坛:穿越元宇宙 沉浸新技术
  19. 微信开发者工具元素快速定位审查元素
  20. 推荐给大家的一款很不错的PHP文库管理系统(知沃文库)-php 开源系统

热门文章

  1. 《CCIE路由和交换认证考试指南(第5版) (第1卷)》——1.6节虚拟交换系统
  2. React文档(五)组件和props
  3. peripheralStateNotificationCB
  4. apache php mysql codeigniter smarty 记录方便查询
  5. Kundera 2.1 发布,NoSQL 的 ORM 框架
  6. 【转】XP/2000无法使用“缩略图查看”、右键无“设置桌面背景”选项问题详解...
  7. sawmill全方位日志分析大师
  8. C#面试题——附答案
  9. cad2016珊瑚_预测有马的硬珊瑚覆盖率
  10. 回归分析检验_回归分析