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函数式编程和链式优化的更多相关文章

  1. 转:JavaScript函数式编程(三)

    转:JavaScript函数式编程(三) 作者: Stark伟 这是完结篇了. 在第二篇文章里,我们介绍了 Maybe.Either.IO 等几种常见的 Functor,或许很多看完第二篇文章的人都会 ...

  2. 转: JavaScript函数式编程(二)

    转: JavaScript函数式编程(二) 作者: Stark伟 上一篇文章里我们提到了纯函数的概念,所谓的纯函数就是,对于相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用,也不依赖外部环 ...

  3. 转:JavaScript函数式编程(一)

    转:JavaScript函数式编程(一) 一.引言 说到函数式编程,大家可能第一印象都是学院派的那些晦涩难懂的代码,充满了一大堆抽象的不知所云的符号,似乎只有大学里的计算机教授才会使用这些东西.在曾经 ...

  4. JavaScript 函数式编程读书笔记1

    概述 这是我读<javascript函数式编程>的读书笔记,供以后开发时参考,相信对其他人也有用. 说明:虽然本书是基于underscore.js库写的,但是其中的理念和思考方式都讲的很好 ...

  5. 一文带你了解JavaScript函数式编程

    摘要: 函数式编程入门. 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 函数式编程在前端已经成为了一个非常热门的话题.在最近几年里,我们看到非常多的应用程序代码库里大量使用着函 ...

  6. JavaScript 函数式编程读书笔记2

    概述 这是我读<javascript函数式编程>的读书笔记,供以后开发时参考,相信对其他人也有用. 说明:虽然本书是基于underscore.js库写的,但是其中的理念和思考方式都讲的很好 ...

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

    JavaScript函数式编程(纯函数.柯里化以及组合函数) 前言 函数式编程(Functional Programming),又称为泛函编程,是一种编程范式.早在很久以前就提出了函数式编程这个概念了 ...

  8. 【大前端攻城狮之路】JavaScript函数式编程

    转眼之间已入五月,自己毕业也马上有三年了.大学计算机系的同学大多都在北京混迹,大家为了升职加薪,娶媳妇买房,熬夜加班跟上线,出差pk脑残客户.同学聚会时有不少兄弟已经体重飙升,开始关注13号地铁线上铺 ...

  9. javascript函数式编程基础随笔

    JavaScript 作为一种典型的多范式编程语言,这两年随着React\vue的火热,函数式编程的概念也开始流行起来,lodashJS.folktale等多种开源库都使用了函数式的特性. 一.认识函 ...

随机推荐

  1. day 42 01--CSS的引入方式及CSS选择器

    01--CSS的引入方式及CSS选择器   本节目录 一 CSS介绍 二 行内样式 三 内接样式 四 外接样式 五 CSS的选择器 六 CSS的高级选择器 七 CSS的属性选择器 八 CSS的伪类选择 ...

  2. 使用Java代码获取Java进程ID的方法

    需要jre/lib下的tools.jar包 public class Test { public static void main(String[] args) throws Exception {  ...

  3. VS2010编译的时候出现fatal error LNK1146: 没有用选项“/out:”指定的参数

    最近安装了下vs2010,发现对硬件要求还是很高的,先是在一个一般台式机上安装出现字体发虚的问题,操作系统也是vista sp2,尝试了网上若干方法还是发虚,总结就是硬件的显卡不行,3年前的机器了:遂 ...

  4. error C2440 “static_cast” 无法从“void (__thiscall C* )(void)...

    1.VC6中,说可以把函数在头文件中定义为:afx_msg void OnProgress()这样 但是在VS2005及以上,要求很严格,必须函数返回值为LRESULT类型,所以在VS2005及以上, ...

  5. Java中将字符串转为驼峰格式

    本文不再更新,可能存在内容过时的情况,实时更新请移步我的新博客:Java中将字符串转为驼峰格式: 使用CaseUtils 对Java字符串进行转换为驼峰格式: CaseUtils.toCamelCas ...

  6. 微信小程序之组件的集合(四)

    这个主要是来开发book的这个大模块的,看看如何优雅的开发出booked模块! 一.book模块的创建 这个就很简单了,创建一个大的框架是很简单的 二.组件的编写 (1)wxml组件页面的编码 首先是 ...

  7. Ubuntn16.04+OpenCV3.1+CUDA8.0+cudnn5.1+caffe配置及问题集锦

    ubuntn16.04 Caffe安装步骤记录(超详尽) 一开始安装好ubuntn16.04后,先安装的opencv3.1,再自己安装的390驱动,cuda8.0和cudnn,之后配置caffe一直不 ...

  8. PHP--通用化API接口数据输出 封装

    /** * 通用化API接口数据输出 * author qinpeizhou * @param $message * @param array $data * @param int $httpCode ...

  9. 省际联动distpicker插件的使用讲解

    1.在使用input页面加载script的引用 <script src="js/distpicker/distpicker.data.js"></script&g ...

  10. dubbo入门学习(三)-----dubbo整合springboot

    springboot节省了大量的精力去配置各种bean,因此通过一个简单的demo来整合springboot与dubbo 一.创建boot-user-service-provider 本篇博文基于上篇 ...