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,一经查实,立即删除!

相关文章

Javascript构造函数的继承

仅供学习参考,原文链接:http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html 今天要介绍的是,对象之间的"继承"的五种方法。 比如,现在有一个"动物"对象的构造函数。 funct…

python输入字符串str_python字符串(str)

#value "raitOrEi"#v value.capitalize()#首字母大写#print(v)#v1 v.casefold()#全部变小写,不只是英文的,其他语言特殊的大小写也变换#print(v1)#v2 v.lower()#只是英文变小写#print(v2)#设置宽度,并将内容居中#20 代指总长度…

html5 audio api 录音,如何使用HTML5 Web Audio API录制我的声音

在webkit浏览器上,您可以将get user media api与webkitGetUserMedia一起使用 – 如html5rocks所示.如果你想用你的声音来创建javascript事件(例如控制屏幕上的对象)你必须分析传入的声音(例如事件1的高频率 – 事件2的低频率,语音分析要复杂得多,见下文)另外,还有chrome的’x-w…

修改密码

在updateservlet.java中写了方法&#xff0c;修改用户密码&#xff0c;代码不成功求大神指教&#xff0c;代码如下&#xff1a; updateadminpw.jsp <% page contentType"text/html;charsetgb2312" pageEncoding"gb2312" %><% taglib uri"ht…

MlLib--逻辑回归笔记

批量梯度下降的逻辑回归可以参考这篇文章&#xff1a;http://blog.csdn.net/pakko/article/details/37878837 看了一些Scala语法后&#xff0c;打算看看MlLib的机器学习算法的并行化&#xff0c;那就是逻辑回归&#xff0c;找到package org.apache.spark.mllib.classification下…

mysql相关命令操作

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

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

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

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

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

hashtable - hashmap

http://www.importnew.com/24822.html转载于:https://www.cnblogs.com/qinqiu/p/9711147.html

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

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

构建之法阅读笔记01

本学期阅读计划有两个&#xff0c;一个是《构建之法》&#xff0c;另一个是《大道至简》。 在快速阅读构建之法后&#xff0c;我想提一下几个问题&#xff1a; 1、软件程序软件工程&#xff0c;那么只会软件工程是怎样具体详细的将程序变成合格的软件的&#xff1f; 2、效能分析…

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

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

博弈论中:纳什均衡、纯策略纳什均衡、混合策略纳什均衡、占优策略

纳什均衡 纳什均衡是由约翰福布斯纳什&#xff08;John Forbes Nash&#xff09;在20世纪50年代提出的博弈论概念&#xff0c;用于描述博弈中的一种稳定状态。在纳什均衡状态下&#xff0c;每个参与者都假定其他参与者的策略是已知的&#xff0c;他们选择的策略是最优的&#…

工具_HBuilder使用快捷方式

HBuilder常用快捷键大概共9类&#xff08;【4 13 3】文件、编辑、插入&#xff1b;【4 9 8】选择、跳转、查找&#xff1b;【1 1 6】运行、工具、视图&#xff09; 1.文件(4) 新建 Ctrl N 关闭 Ctrl F4 全部关闭 Ctrl Shift F4 属性 Alt Enter 2.编辑(13) 激活代码助…

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

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

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

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

fis

fis3实时刷新 npm install -g fis3 进入相关目录 发布&#xff1a; fis3 release 启动&#xff1a; fis3 server start // 服务启动后&#xff0c;会一直存在&#xff0c;重启或者fis3 server stop 才会关闭服务 自动刷新 fis3 release -wL关闭服务 fis3 server stop …

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

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

微型计算机一般不采用的控制方式,微型计算机控制作业.doc

作业一PID控制器引言在实际的过程控制与运动控制系统中&#xff0c;PID家族占据有相当的地位&#xff0c;据统计&#xff0c;工业控制的控制器中PID类控制占有90%以上。PID控制器是最早出现的控制器类型&#xff0c;因为其结构简单&#xff0c;各个控制器参数有着明显的物理意义…

js根据毫米/厘米算像素px

<html><meta http-equiv"content-type" content"text/html;charsetutf-8"><body> 纸张宽度(毫米mm)&#xff1a;<input type"text" id"width" value"10"> <span id"width_px"><…