命令式和声明式
- 声明式编程是一种编程风格
- 采用声明式编程风格,代码对执行结果的描述远胜于执行过程;语法本身描述了将会发生什么,相关的执行细节被隐藏。
- 采用命令式编程风格,代码重点关注的是达成目标的具体过程
函数式编程
- 函数式编程是声明式编程的一部分
- 一个函数被当作第一类成员时,他不仅可以被声明为一个变量,而且可以被当成函数参数传递,甚至可以作为函数的执行结果被返回。函数就是数据,可以像变量一样,被保存、检索或者在应用程序内部传递。
// 被声明成一个变量
const log = message => console.log(message) ;
// 作为其他函数的参数
const insideFn = logger => logger('hello');
// 作为其他函数的执行结果被返回
const createScream = logger => message =>
logger(message.toUpperCase()+'!!!')
// 一个箭头以上,便是我们声明的是高阶函数
函数式编程的核心概念
- 不可变性:在不修改原生数据结构的情况下,在这些数据结构的口碑上进行编辑,并使用他们取代原生数据;
// 改变原有数据
let color_lawn={
title: 'lawn',
color: '#00ff00',
rating: 0
};
function rateColor(color, rating){
color.rating = rating;
return color;
};
// 不改变原生数据
var rateColor = function (color, rating){
return Object.assign({}, color, {rating: rating});
}
// or
const rateColor = (color, rating) =>
({
color,
rating
})
// 注意圆括号包裹返回对象式必须的,因为箭头不能指向一个对象的花括号
- 纯函数:
- 是一个返回结果只依赖于输入参数的函数。
- 纯函数至少需要接收一个参数并且总返回一个值或者其他函数。
- 不应该修改或者影响任何传给他的参数
- 易于可测试
// 非纯函数,没有接受参数,没有返回值或函数,而且修改了其作用域之外的变量frederick
var frederick = {
name: 'Frederrick Douglass',
canRead: false,
canWrite: false
};
function selfEducate () {
frederick.canRead = true;
frederick.canWrite = true;
return frederick;
};
// 纯函数
const selfEducate = person =>
({
...person,
canRead: true,
canWrite: true
})
// react 中,UI用纯函数表示
const Header = props => <h1>{props.title}</h1>
- 数据转换:将数据从一个类型转换到另一个类型。介绍几个不会改变原数据本身,而是在原数据基础上,进行操作后,返回一个新数据。
- join();
- filter();
- map();
- Object.keys()
- reduce()
- 高阶函数:可以操作其他函数的函数。可以将函数当作参数传递,也可以返回一个函数,或者两个兼而有之。
// 将其他函数当作参数传递的函数
Array.map、Array.filter、Array.reduce
// 柯里化(Curring):将某个操作中已经完成的结果保留,知道其余部分后续也完成后可以一并提供的机制
const userLogs = userName => message =>
console.log(`${userName}->${message}`);
const log = userLogs('world');
log('hello~'); // world->hello~
const countDown = (value, fn) => {
fn(value);
return (value > 0) ? countDown(value-1, fn) : value
};
countDown(10, value => console.log(value))
- 合成:将小型的纯函数整合到一起。合成他们,以串联或并联的方式对他们进行调用,或者可以使用点负好连接在一起,其作用是获得上一个函数的返回值。合成的目标是通过整合若干简单函数构成一个更高阶的函数。