[学习笔记]JavaScript之函数式编程
欢迎指导与讨论:)
前言
函数式编程能使我们的代码结构变得简洁,让代码更接近于自然语言,易于理解。
一、减少不必要的函数嵌套代码
(1)当存在函数嵌套时,若内层函数的参数与外层函数的参数一致时,可以这样子写。
- // 一个内层函数
- function call( num, index ){
- console.log (num + ' ' + index );
- }
- // 啰嗦的写法
- [ 1, 2, 3 ].map(function( num, index ){
- return call( num, index );
- })
- // 简洁的写法
- [ 1, 2, 3 ].map( call );
(2)当存在函数嵌套时,若内层函数的参数与外层函数的参数一致时,可以这样子写。
- // 啰嗦的写法
- var app = (function( ){
- var init = function( name, value ){
- Db.init( name, value);
- }
- return { init: init }
- })( )
- // 简洁的写法
- var app = { init: Db.init }
(3)小结,这种写法主要依靠于,函数发生嵌套时,内外函数所接受的参数时一致。并且这种写法从可读性上看,是忽略了参数传递的过程。
二、尽量使用纯函数 —— 让副作用在可控范围内发生
纯函数是一类,只要输入相同,每次必能返回相同输出的一类函数。它要求:尽可能不与与函数体外的变量打交道,让结果尽可能与函数体外的任何变量无关,函数不影响输入的数据等等。另外,基于纯函数,能够使用缓存,实现尽可能少的复杂运算 —— react reselect就是一个例子。同时也能提高函数的可测试性。
(1)尽可能地不影响原有数据
- // 原数据
- var xs = [1,2,3,4,5];
- // 纯的
- xs.slice(0,3);
- // 不纯的
- xs.splice(0,3);
(2)使结果尽可能和函数体外部变量无关
- // 不纯的
- var minimum = 21;
- var checkAge = function(age) {
- return age >= minimum;
- };
- // 纯的
- var checkAge = function(age, minimum ) {return age >= minimum;
- };
三、柯里化 —— 动态创建新函数
柯里化是动态地创建函数的一种写法,让函数先处理一部分逻辑,然后再让函数体内再次返回一个函数,达到函数配置、惰性求值的效果。结合闭包,能实现良好的封装效果。
同时,柯里化也称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果。因此柯里化的过程是逐步传参,逐步缩小函数的适用范围,逐步求解的过程。
- (1)使用柯里化,进行函数的创建与配置
- function testRegEx( RegEx ) {
- // 先进行配置
- var regEx = RegEx;
- // 惰性求值,返回函数引用
- return function( string ) {
- return regEx.test( string );
- }
- }
- // 使用方法:
- testRegEx( /hello/g )('Ben said hello!') // 返回true
- // 另一种使用方法:
- var hasHello = testRegEx(/hello/g);
- hasHello('Ben said hello!') // 返回true
(2)使用柯里化,返回实用的接口
- function append ( parent,child ){
- parent.appendChild( child );
- return function( ){
- child.remove( );
- }
- }
- // 使用:
- var remove = append( node1, node2 );
- // 调用返回的函数
- remove( );
四、函数组合 —— 更佳的可读性
顾名思义,组合函数是将多个函数进行组合成一个函数。通过自定义函数组合函数的compose,可以提高一定的函数嵌套可读性。当数据需要从一层层的函数流经时(Pipe管道),我们推荐使用函数组合,来提高可读性。
(1)自定义函数组合函数
- // 建立一个,从右至左,管道式的函数组合 函数
- var compose = function( ...list ) {
- var last = list[ list.length -1 ];
- var rest = list.slice( 0, -1 );
- return ( ...args ) => rest.reduceRight(( preValue, currentFunc) => currentFunc( preValue ), last( ...args))
- }
- // 使用方法:
- // 加感叹号
- var exclaim = ( x ) => x + '!!!!';
- // 变大写
- var upperCase = ( x ) => x.toUpperCase( );
- // 加其他符号
- var other= ( x ) => x + '@@@';
- // 函数组合 ------> 函数从右往左地执行,函数执行过程的可读性非常高
- var last = compose( other, upperCase, exclaim);
- last('hello')
- // 返回: HELLO!!!!@@@
五、函数声明式
与平时需要时刻关心所有细节的命令式编程相比,函数声明式会让我们轻松一些,因为它没有"先做这个,再做那个"的命令式代码,而是转为"我需要什么样的数据"的表达式,前者是表达怎么做,后者是表达做什么。同时,函数声明式也能让代码更加优雅。
(1)一个函数声明式例子
- // 命令式
- var makes = [];
- for (i = 0; i < cars.length; i++) {
- makes.push(cars[i].make);
- }
- // 声明式
- var makes = cars.map(function(car){ return car.make; });
[学习笔记]JavaScript之函数式编程的更多相关文章
- Python学习笔记二:函数式编程
1:Python中,内置函数名相当于一个变量,指向内置函数.所以可以通过函数名调用相应函数,也可以给函数名赋值,改变它的内容,如:可以把另一个函数变量赋值给它,那它就指向了所赋值的函数了. 2:高级函 ...
- #学习笔记#——JavaScript 数组部分编程(一)
来自牛客网的js编程题 1.移除数组 arr 中的所有值与 item 相等的元素.不要直接修改数组 arr,结果返回新的数组 function remove(arr, item) { if(!Arra ...
- #学习笔记#——JavaScript 数组部分编程(七)
24.柯里化 首先想解释一下,“柯里化”的意思, [在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结 ...
- #学习笔记#——JavaScript 数组部分编程(六)
14. 题目描述 实现一个打点计时器,要求 1.从 start 到 end(包含 start 和 end),每隔 100 毫秒 console.log 一个数字,每次数字增幅为 1 2.返回的对象中需 ...
- #学习笔记#——JavaScript 数组部分编程(五)
11.为数组 arr 中的每个元素求二次方.不要直接修改数组 arr,结果返回新的数组 function square(arr) { var resultArr=new Array(); for(va ...
- #学习笔记#——JavaScript 数组部分编程(四)
7.合并数组 arr1 和数组 arr2.不要直接修改数组 arr,结果返回新的数组 function concat(arr1, arr2) { return arr1.concat(arr2); } ...
- #学习笔记#——JavaScript 数组部分编程(三)
3.在数组 arr 末尾添加元素 item.不要直接修改数组 arr,结果返回新的数组 主要考察数组的concat方法,代码如下: arr.concat(item); concat 方法不修改原数组. ...
- #学习笔记#——JavaScript 数组部分编程(二)
2.移除数组 arr 中的所有值与 item 相等的元素,直接在给定的 arr 数组上进行操作,并将结果返回 function removeWithoutCopy(arr, item) { if(!A ...
- Scala学习教程笔记二之函数式编程、Object对象、伴生对象、继承、Trait、
1:Scala之函数式编程学习笔记: :Scala函数式编程学习: 1.1:Scala定义一个简单的类,包含field以及方法,创建类的对象,并且调用其方法: class User { private ...
随机推荐
- 用scikit-learn进行LDA降维
在线性判别分析LDA原理总结中,我们对LDA降维的原理做了总结,这里我们就对scikit-learn中LDA的降维使用做一个总结. 1. 对scikit-learn中LDA类概述 在scikit-le ...
- 【Win 10 应用开发】启动远程设备上的应用
这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用.激活远程应用需要以下前提: 系统必须是build 14393 ...
- Android权限管理之Android 6.0运行时权限及解决办法
前言: 今天还是围绕着最近面试的一个热门话题Android 6.0权限适配来总结学习,其实Android 6.0权限适配我们公司是在今年5月份才开始做,算是比较晚的吧,不过现在Android 6.0以 ...
- .net 分布式架构之业务消息队列
开源QQ群: .net 开源基础服务 238543768 开源地址: http://git.oschina.net/chejiangyi/Dyd.BusinessMQ ## 业务消息队列 ##业务消 ...
- springMVC初探--环境搭建和第一个HelloWorld简单项目
注:此篇为学习springMVC时,做的笔记整理. MVC框架要做哪些事情? a,将url映射到java类,或者java类的方法上 b,封装用户提交的数据 c,处理请求->调用相关的业务处理—& ...
- 以项目谈WebGIS中Web制图的设计和实现
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景介绍 一般WebGIS项目中,前端展示数据的流程基本是先做数据入 ...
- 【绝对干货】仿微信QQ设置图形头像裁剪,让你的App从此炫起来~
最近在做毕业设计,想有一个功能和QQ一样可以裁剪头像并设置圆形头像,额,这是设计狮的一种潮流. 而纵观现在主流的APP,只要有用户系统这个功能,这个需求一般都是在(bu)劫(de)难(bu)逃(xue ...
- Android—应用程序开机自启
android开机时候会发送开机广播,我们想要收到广播知道手机开机,才能启动我们的应用程序. 首先要在配置文件中添加相应权限: <uses-permission android:name=&qu ...
- (转) 将ASP.NET Core应用程序部署至生产环境中(CentOS7)
原文链接: http://www.cnblogs.com/ants/p/5732337.html 阅读目录 环境说明 准备你的ASP.NET Core应用程序 安装CentOS7 安装.NET Cor ...
- hbase集群安装与部署
1.相关环境 centos7 hadoop2.6.5 zookeeper3.4.9 jdk1.8 hbase1.2.4 本篇文章仅涉及hbase集群的搭建,关于hadoop与zookeeper的相关部 ...