JavaScript函数式编程

函数式编程在前端已经成为了一个热门的话题,近几年很多的应用程序代码库里大量使用着函数式编程思想。这里对JavaSctipt中的函数式编程做一个简单了解。

什么是函数式编程

函数式编程是一种编程范式,主要是利用函数把运算过程封装起来,通过组合各种函数来计算结果。函数式编程意味着开发者可以在更短的时间内编写具有更少错误的代码。

函数式编程的简单例子

假设要把一个字符串转换成每个单词首字母大写,可以这样来实现:

var string = 'i do like yanggb';
var result = string
    .split(' ')
    .map(v => v.slice(0, 1).toUpperCase() + v.slice(1))
    .join(' ');

在这个例子中,为了得到想要的结果,先调用split()方法将字符串转换成数组,然后再调用map()方法把各个元素的首字母转换成大写,最后再调用join()方法把数组转换成字符串。这里的整个过程就是join(map(split(str))),体现了函数式编程的核心思想:通过函数对数据进行转换。

函数式编程的两个基本特点

通过上面的例子可以得到函数式编程有两个基本特点:

1.通过函数来对数据进行转换。

2.通过串联多个函数来求最终结果。

与命令式编程、声明式编程的对比

这里简单对比下函数式编程与命令式编程、声明式编程的区别。

什么是命令式编程

命令式编程,就是通过编写一条又一条的指令去让计算机执行一些动作,这其中一般都会涉及到很多繁杂的细节。命令式代码中会频繁使用语句来完成某些行为,比如for、if、switch和throw等语句。

// 命令式编程
var vegetable = ['菠菜', '冬瓜', '太空椒', '番茄', '油菜'];
var food = [];
for (var i = 0; i < vegetable.length; i++) {
    food.push(vegetable[i]);
}

什么是声明式编程

声明式编程,就是通过写表达式的方法来声明我们想要做什么,而不是通过一步一步的指令,相当于是对命令式编程的一种简单封装。这些表达式通常是某些函数调用的复合、一些值和操作符,用来计算出想要的结果值。

// 声明式编程
var food = vegetable.map(c => c);

函数式编程与命令式编程、声明式编程的区别

从上面的例子中可以看出,声明式的写法是一个表达式,无需关心如何进行计数器迭代,返回的数组如何收集,它指明的是做什么,而不是怎么做。函数式编程的一个明显的好处就是这种声明式的代码,对于无副作用的纯函数,完全可以不考虑函数内部是如何实现的,开发者可以专注于编写业务代码。

函数式编程的特性

函数式编程有一些常见的特性。

无副作用

无副作用的特性,是指调用函数的时候不会修改外部的状态,即一个函数调用n次之后依然返回同样的结果。

var a = 1;

function f1() { // 多次调用结果不一样
    a++; // 含有副作用,它修改了外部变量 a
    return a;
}

function f2(a) { // 多次调用结果一样
    return a + 1;  // 无副作用,没有修改外部状态
}

透明引用

透明引用的特性,是指一个函数只会用到传递给它的变量以及自己内部创建的变量,不会使用到其他变量(外部变量)。这个特性与无副作用的特性相呼应。

var a = 1, b = 2;

function f1() { // 函数内部使用的变量并不属于它的作用域
    return a + b;
}

function f2(a, b) { // 函数内部使用的变量是显式传递进去的
    return a + b;
}

不可变变量

不可变变量的特性,指的是一个变量一旦创建完成之后,就不能再被修改,任何修改都会生成一个新的变量。使用不可变变量最大的好处是线程安全,多个线程可以同时访问同一个不可变变量,而不用担心状态不一致的问题,使得并行变得容易实现。

但是由于JavaScript原生不支持不可变变量,需要通过第三方库(比如Immutable.js和Mori等)来实现。

var obj = Immutable({a: 1});
var obj2 = obj.set('a', 2);
console.log(obj); // Immutable({a: 1})
console.log(obj2); // Immutable({a: 2})

函数是一等公民

常说函数是JavaScript的一等公民,指的是函数与其他数据类型一样处于平等地位。可以将函数赋值给其他变量,也可以作为参数传入另一个函数,或者作为别的函数的返回值。JavaScript中的闭包、高阶函数、函数柯里化和函数组合都是围绕这一特性的应用。

常见的函数式编程模型

常见的函数式编程模型有闭包、高阶函数、函数柯里化和函数组合。

闭包(Closure)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/b7b2812b46ac53c212d2b97494cf02ba.html