javascript函数式编程和链式优化
1、函数式编程理解
函数式编程可以理解为,以函数作为主要载体的编程方式,用函数去拆解、抽象一般的表达式
与命令式相比,这样做的好处在哪?主要有以下几点:
(1)语义更加清晰
(2)可复用性更高
(3)可维护性更好
(4)作用域局限,副作用少
// 数组中每个单词,首字母大写
// 一般写法
const arr = ['apple', 'pen', 'apple-pen'];
for(const i in arr){
const c = arr[i][0];
arr[i] = c.toUpperCase() + arr[i].slice(1);
}
console.log(arr); //[ 'Apple', 'Pen', 'Apple-pen' ] // 函数式写法一
function upperFirst(word) {
return word[0].toUpperCase() + word.slice(1);
} function wordToUpperCase(arr) {
return arr.map(upperFirst);
}
console.log(wordToUpperCase(['apple', 'pen', 'apple-pen'])); //[ 'Apple', 'Pen', 'Apple-pen' ] // 函数式写法二
console.log(arr.map(['apple', 'pen', 'apple-pen'], word => word[0].toUpperCase() + word.slice(1))); //[ 'Apple', 'Pen', 'Apple-pen' ]
当情况变得更加复杂时,表达式的写法会遇到几个问题:
(1)表意不明显,逐渐变得难以维护
(2)复用性差,会产生更多的代码量
(3)会产生很多中间变量
函数式编程很好的解决了上述问题。首先参看 函数式写法一,它利用了函数封装性将功能做拆解(粒度不唯一),并封装为不同的函数,而再利用组合的调用达到目的。这样做使得表意清晰,易于维护、复用以及扩展。其次利用 高阶函数,Array.map 代替 for…of 做数组遍历,减少了中间变量和操作。
而 函数式写法一 和 函数式写法二 之间的主要差别在于,可以考虑函数是否后续有复用的可能,如果没有,则后者更优。
链式优化
// 计算数字之和
// 一般写法
console.log(1 + 2 + 3 - 4) // 函数式写法
function sum(a, b) {
return a + b;
} function sub(a, b) {
return a - b;
}
console.log(sub(sum(sum(1, 2), 3), 4);
函数式代码在写的过程中,很容易造成 横向延展,即产生多层嵌套,随着函数的嵌套层数不断增多,导致代码的可读性大幅下降,还很容易产生错误。
在这种情况下,我们可以考虑多种优化方式,比如下面的 lodash 的链式写法。
const utils = {
chain(a) {
this._temp = a;
return this;
},
sum(b) {
this._temp += b;
return this;
},
sub(b) {
this._temp -= b;
return this;
},
value() {
const _temp = this._temp;
this._temp = undefined;
return _temp;
}
};
console.log(utils.chain(1).sum(2).sum(3).sub(4).value()); //这样改写后,结构会整体变得比较清晰,而且链的每一环在做什么也可以很容易的展现出来。
函数的嵌套和链式的对比还有一个很好的例子,那就是 回调函数 和 Promise 模式。
// 顺序请求两个接口 // 回调函数
import $ from 'jquery';
$.post('a/url/to/target', (rs) => {
if(rs){
$.post('a/url/to/another/target', (rs2) => {
if(rs2){
$.post('a/url/to/third/target');
}
});
}
}); // Promise
import request from 'catta'; // catta 是一个轻量级请求工具,支持 fetch,jsonp,ajax,无依赖
request('a/url/to/target')
.then(rs => rs ? $.post('a/url/to/another/target') : Promise.reject())
.then(rs2 => rs2 ? $.post('a/url/to/third/target') : Promise.reject());
随着回调函数嵌套层级和单层复杂度增加,它将会变得臃肿且难以维护,而 Promise 的链式结构,在高复杂度时,仍能纵向扩展,而且层次隔离很清晰。
javascript函数式编程和链式优化的更多相关文章
- 转:JavaScript函数式编程(三)
转:JavaScript函数式编程(三) 作者: Stark伟 这是完结篇了. 在第二篇文章里,我们介绍了 Maybe.Either.IO 等几种常见的 Functor,或许很多看完第二篇文章的人都会 ...
- 转: JavaScript函数式编程(二)
转: JavaScript函数式编程(二) 作者: Stark伟 上一篇文章里我们提到了纯函数的概念,所谓的纯函数就是,对于相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用,也不依赖外部环 ...
- 转:JavaScript函数式编程(一)
转:JavaScript函数式编程(一) 一.引言 说到函数式编程,大家可能第一印象都是学院派的那些晦涩难懂的代码,充满了一大堆抽象的不知所云的符号,似乎只有大学里的计算机教授才会使用这些东西.在曾经 ...
- JavaScript 函数式编程读书笔记1
概述 这是我读<javascript函数式编程>的读书笔记,供以后开发时参考,相信对其他人也有用. 说明:虽然本书是基于underscore.js库写的,但是其中的理念和思考方式都讲的很好 ...
- 一文带你了解JavaScript函数式编程
摘要: 函数式编程入门. 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 函数式编程在前端已经成为了一个非常热门的话题.在最近几年里,我们看到非常多的应用程序代码库里大量使用着函 ...
- JavaScript 函数式编程读书笔记2
概述 这是我读<javascript函数式编程>的读书笔记,供以后开发时参考,相信对其他人也有用. 说明:虽然本书是基于underscore.js库写的,但是其中的理念和思考方式都讲的很好 ...
- JavaScript函数式编程(纯函数、柯里化以及组合函数)
JavaScript函数式编程(纯函数.柯里化以及组合函数) 前言 函数式编程(Functional Programming),又称为泛函编程,是一种编程范式.早在很久以前就提出了函数式编程这个概念了 ...
- 【大前端攻城狮之路】JavaScript函数式编程
转眼之间已入五月,自己毕业也马上有三年了.大学计算机系的同学大多都在北京混迹,大家为了升职加薪,娶媳妇买房,熬夜加班跟上线,出差pk脑残客户.同学聚会时有不少兄弟已经体重飙升,开始关注13号地铁线上铺 ...
- javascript函数式编程基础随笔
JavaScript 作为一种典型的多范式编程语言,这两年随着React\vue的火热,函数式编程的概念也开始流行起来,lodashJS.folktale等多种开源库都使用了函数式的特性. 一.认识函 ...
随机推荐
- day 42 01--CSS的引入方式及CSS选择器
01--CSS的引入方式及CSS选择器 本节目录 一 CSS介绍 二 行内样式 三 内接样式 四 外接样式 五 CSS的选择器 六 CSS的高级选择器 七 CSS的属性选择器 八 CSS的伪类选择 ...
- 使用Java代码获取Java进程ID的方法
需要jre/lib下的tools.jar包 public class Test { public static void main(String[] args) throws Exception { ...
- VS2010编译的时候出现fatal error LNK1146: 没有用选项“/out:”指定的参数
最近安装了下vs2010,发现对硬件要求还是很高的,先是在一个一般台式机上安装出现字体发虚的问题,操作系统也是vista sp2,尝试了网上若干方法还是发虚,总结就是硬件的显卡不行,3年前的机器了:遂 ...
- error C2440 “static_cast” 无法从“void (__thiscall C* )(void)...
1.VC6中,说可以把函数在头文件中定义为:afx_msg void OnProgress()这样 但是在VS2005及以上,要求很严格,必须函数返回值为LRESULT类型,所以在VS2005及以上, ...
- Java中将字符串转为驼峰格式
本文不再更新,可能存在内容过时的情况,实时更新请移步我的新博客:Java中将字符串转为驼峰格式: 使用CaseUtils 对Java字符串进行转换为驼峰格式: CaseUtils.toCamelCas ...
- 微信小程序之组件的集合(四)
这个主要是来开发book的这个大模块的,看看如何优雅的开发出booked模块! 一.book模块的创建 这个就很简单了,创建一个大的框架是很简单的 二.组件的编写 (1)wxml组件页面的编码 首先是 ...
- Ubuntn16.04+OpenCV3.1+CUDA8.0+cudnn5.1+caffe配置及问题集锦
ubuntn16.04 Caffe安装步骤记录(超详尽) 一开始安装好ubuntn16.04后,先安装的opencv3.1,再自己安装的390驱动,cuda8.0和cudnn,之后配置caffe一直不 ...
- PHP--通用化API接口数据输出 封装
/** * 通用化API接口数据输出 * author qinpeizhou * @param $message * @param array $data * @param int $httpCode ...
- 省际联动distpicker插件的使用讲解
1.在使用input页面加载script的引用 <script src="js/distpicker/distpicker.data.js"></script&g ...
- dubbo入门学习(三)-----dubbo整合springboot
springboot节省了大量的精力去配置各种bean,因此通过一个简单的demo来整合springboot与dubbo 一.创建boot-user-service-provider 本篇博文基于上篇 ...