【转载自】:https://blog.csdn.net/Fundebug/article/details/90709826
【前言】:今天再逛csdn时,偶然间看到了上面这篇文章。本来自以为已经了解了函数式编程,但当看到这篇文章时,才发现自己之前的见解有多么肤浅,因此决定重新整理有关声明式编程、命令式编程以及函数式编程相关的概念、以及知识点,方便未来某一时刻快速回忆以及使用。
声明式编程关注点由如何做转变为做什么,避免了各种副作用(常说的副作用是指方法为纯函数,内部状态的变化不会对外部的变量造成影响)。声明式编程不关注对象的实现细节,只关注在执行过程中计算机应该做什么,当我们使用正则表达式进行正则匹配的过程中,声明式编程方式让我们关注正则表达式要做什么以及所匹配的内容,但并不关注正则表达式底层具体所做了哪些事情。同理html标签也是声明式编程的一种,只需要告知计算机我们声明了什么,无需关注他内部到底如何实现。典型的声明式编程如数据库查询语言、正则表达式等。
//声明式编程 告知机器做什么,隐藏具体的实现细节
let arr = [1, 2, 3, 4, 5];
arr.filter((item) => item % 2 == 0);
//命令式编程,关注实现过程
let arr = [1, 2, 3, 4, 5];
let result = [];
for(let i=0, len = arr.length; i < len; i++) {
let cacheItem = arr[i];
if( cacheItem % 2 == 0 ) {
result.push(cacheItem);
}
}
//函数式编程,纯函数实现
let arr = [1, 2, 3, 4, 5];
function findOddNumber(resource) {
let result = [];
for(let i=0, len = arr.length; i < len; i++) {
let cacheItem = arr[i];
if( cacheItem % 2 == 0 ) {
result.push(cacheItem);
}
}
return result;
}
findOddNumber(arr);
命令式编程关注点与声明式编程的关注点正好相反,其更关注实现的细节,主要思想是关注计算机执行的步骤,即一步一步告诉计算机先做什么再做什么。所谓命令式编程,是以命令为主的,给机器提供一条又一条的命令序列让其原封不动的执行。程序执行的效率取决于执行命令的数量。因此才会出现大O表示法等等表示时间空间复杂度的符号。
//命令式编程
let cart=[];
function addCart(commodity){
if(!commodity){
return throw new Error('Parameters required');
}
for(let i = 0, len = cart.length; i
函数式编程是声明式编程的一部分,因为他们思想是一致的:即只关注做什么而不是怎么做。但函数式编程除了对声明式编程的相似处之外,同时他也利用了js函数能够作为参数传递的特点。函数式编程最重要的特点是“函数第一位”,即函数可以出现在任何地方。
函数式编程的特性:
(a)、不可变性(Immutability):不可变性是指函数不存在副作用,如果需要修改,需要克隆新的备份数据进行处理
(b)、纯函数(Pure Functions):纯函数是始终接受一个或多个参数并计算参数并返回数据或函数的函数
(c)、数据转换(Data Transformations):对传递的数据克隆备份后,进行数据的处理,最终返回新的对象,避免副作用
(d)、闭包以及高阶函数 (Higher-Order Functions):高阶函数是将函数作为参数或返回函数的函数,闭包不做解释
(e)、递归:递归是一种函数在满足一定条件之前调用自身的技术。
(f)、组合:常用的混合函数,将多个对象混合为一个新的对象。
(g)、惰性计算:在惰性计算中,表达式不是在绑定到变量时立即计算,而是在求值程序需要产生表达式的值时进行计算。