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

c0acd968ef028051ce3efc96043b4ad0.png

高阶函数的定义

在《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已经不需要这么写了公众号:

ad4a4f47433d8443926ae049361d2998.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/396713.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql相关命令操作

2019独角兽企业重金招聘Python工程师标准>>> 远程连接容器中的mysql:mysql -h 192.168.5.116 -P 3306 -u root -p123456 启动mysql容器: $ sudo docker pull mysql:5.6.35 $ sudo docker run --name mysql -p 12345:3306 -e MYSQL_ROOT_PASSW…

html实体注册商标,html 注册商标,html 注册商标代码

html中注册的页面用什么标签写好对于html中的注册页面,策朋专业办理商标注册、专利申请、版权登记保护,需要一个表格。使用标签,输入和按钮标签来组合成就。使用html作为注册页面。实际上,只要您能达到期望的效果,它的…

java已知一个二叉树_#二叉树复习#

#二叉树复习#目录满二叉树完全二叉树平衡二叉树二叉树的主要性质--二叉树的度--二叉树的深度计算二叉树的遍历其他符号变量结点总数深度度为0的结点数/叶子结点数度为1的结点数度为2的结点数什么是满二叉树?二叉树每层的结点数为。满二叉树总结点数:。图…

java 反射机制_基础篇:深入解析JAVA反射机制

反射的概念java 的放射机制:在程序运行时,程序有能力获取一个类的所有方法和属性;并且对于任意一个对象,可以调用它的任意方法或者获取其属性通俗解析:java 文件需要编译成. class 文件才能被 jvm 加载使用, 对象的. c…

html div float center,跨浏览器实现float:center

跨浏览器实现float:center互联网 发布时间:2008-10-17 19:26:11 作者:佚名 我要评论原文:http://www.macji.com/blog/article/to-achieve-cross-browser-css-float-center/to-achieve-cross-browser-css-float-center/我们都知道float…

oracle左连接没用_一周零基础学完Oracle数据库第三天02

四、 多表查询1 什么是多表查询多表查询:当查询的数据并不是来源一个表时,需要使用多表链接操作完成查询。根据 不同表中的数据之间的关系查询相关联的数据。多表链接方式: 内连接:连接两个表,通过相等或不等判断链接列…

weblogic启动项目报错找不到类_启动类报错是经常出现的事但是单一的从一个地方找原因会越找越错...

Error starting ApplicationContext. To display the conditions report rerun your application with debug enabled.当我们看到这个报错的时候有的说是jar包重复,有的说是Controller包和Application包处于平行位置,还有的觉得是RequestMapping的valu…

深入理解javascript原型和闭包(7)——原型的灵活性

在Java和C#中,你可以简单的理解class是一个模子,对象就是被这个模子压出来的一批一批月饼(中秋节刚过完)。压个啥样,就得是个啥样,不能随便动,动一动就坏了。 而在javascript中,就没…

c语言为什么有这么多的编程环境?_为什么98%的程序员学编程都会从C语言开始?...

在互联网蓬勃发展的时代,有一类人做出了巨大的贡献,这一群人被大家称之为程序员,怎样才能成为一名优秀的程序员呢,为什么每一个程序员都需要学习C语言呢?就让我来跟大家分享分享:壹第一:相比较其…

Angular 星级评分组件

一、需求演变及描述: 1. 有一个“客户对公司的总体评价”的字段(evalutation)。字段为枚举类型,0-5,对应关系为:0-暂无评价,1-很差,2-差,3-一般,4-好&#xf…

计算机网络怎么查看连接打印机驱动,如何检测网络打印机是否已成功连接到计算机[检测方法]...

大概很多婴儿都像以前的编辑一样. 使用网络打印机时,有时它们可​​以打印打印机没有和电脑连接,有时却不能. 那么如何检测网络打印机是否已成功连接到计算机?跟随编辑器往下看.系统反复提示“无法打印”,因此本来很忙的小修几乎快…

a - 数据结构实验之图论一:基于邻接矩阵的广度优先搜索遍历_数据结构--图

故事凌 今天基本知识点图可说是所有数据结构里面知识点最丰富的一个, 自己笨的知识点如下:阶(oRDER), 度: 出度(out-Degree), 入度(in-Degree)树(Tree), 森林(Forest), 环(Loop)有向图(Directed Graph), 无向图(Undirected Graph), 完全有向图, 完全无向图连通图(Connected Gra…

vim: vimrc

2019独角兽企业重金招聘Python工程师标准>>> 打造vim CIDE http://blog.csdn.net/doc_sgl/article/details/47205779 转载于:https://my.oschina.net/u/2528742/blog/843176

计算机二级考试试题在线看,【TOP182015年全国计算机二级考试试题题库.doc文档免费在线阅读材料】...

TOP182015年全国计算机二级考试试题题库.doc文档免费在线阅读《2015年全国计算机二级考试试题题库.doc》由会员分享,可免费在线阅读全文,更多与《TOP182015年全国计算机二级考试试题题库.doc文档免费在线阅读》相关文档资源请在帮帮文库(www.woc88.com)数…

不用开发实现RDS RDWeb门户美化和个性化

个性化RDWeb界面RDWeb原生界面相对比较简洁,每个企业部署的RDWeb都是千篇一律的,有些用户可能希望将网页装饰得个性化点。在谈到自定义Web界面,第一反应可能是使用代码进行编写,但是这里要和大家分享的是无代码美化和自定义RDWeb界…

其他大神的配置 nginx 配置参考

2019独角兽企业重金招聘Python工程师标准>>> user nginx nginx; worker_processes 2; #error_log logs/error.log; error_log logs/error.log notice; #error_log logs/error.log info; pid logs/nginx.pid; google_perftools_profiles /tmp/tcmalloc; worker_rlim…

小孩用计算机做作业怎么表达,计算机作业

满意答案尧Dreaman夕2014.09.25采纳率:40% 等级:10已帮助:1121人Windows中可以设置、控制计算机硬件配置和修改桌面布局的应用程序是( D)A) Word B) Excel C)资源管理器 D)控制面板多窗口的切换可以通过(D )来实现A)在任务栏上用鼠标单击右…

[No0000178]改善C#程序的建议1:非用ICloneable不可的理由

好吧,我承认,这是一个反标题,实际的情况是:我找不到一个非用ICloneable不可的理由。事实上,接口ICloneable还会带来误解,因为它只有一个Clone方法。 我们都知道,对象的拷贝分为:浅拷…

SOM 的两种算法

我参考了这篇文章http://www.scholarpedia.org/article/Kohonen_network另一个很好的演示在这里http://www.math.le.ac.uk/people/ag153/homepage/PCA_SOM/PCA_SOM.htmlSOMt是训练步一个输入数据是n维向量待训练的是一堆节点,这堆节点之间有边连着,通常是…

秒懂,Java 注解 (Annotation)你可以这样学

转自: https://blog.csdn.net/briblue/article/details/73824058 文章开头先引入一处图片。 这处图片引自老罗的博客。为了避免不必要的麻烦,首先声明我个人比较尊敬老罗的。至于为什么放这张图,自然是为本篇博文服务,接下来我自会说明。好了…