JavaScript 函数式编程

本文是 JSConf 上的一篇笔记

What is functional programming?

  • 一种编程范式 a programming paradigm
  • 一种编码风格 a coding style
  • 一种思考问题的方式 a mindset

Why functional JavaScript?

  • JS 的面向对象非常令人困惑
  • safer
  • easier to debug/maintain

要怎么做

函数式编程中你会想用函数来做所有事情,用函数来表达程序中的所有内容

接收输入 提供输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
Not functional
命令式风格 先做什么,再做什么,再最后做什么...
没有函数,不是以如何输入会转换为输出来表达
*/
var name = 'jack';
var greeting = "Hi, I'm ";
console.log(greeting + name)

// functional
function greet(name) {
return "Hi I'm " + name;
}

greet('Anjana');

使用纯函数

Avoid side effects
use “pure” functions

副作用指当调用函数时,除了返回可能的函数值之外,还对主调用函数产生附加的影响。例如修改全局变量(函数外的变量),修改参数等。在某些情况下函数副作用会给程序设计带来不必要的麻烦,给程序带来十分难以查找的错误,并降低程序的可读性与可移植性。

1
2
3
4
5
// Not pure
var name = 'Anjana';
function greet() {
console.log("Hi, I'm " + name)
}

Use Higher-order Functions

functions can be inputs/outputs

1
2
3
4
5
6
7
8
function makeAdjectifier(adjective) {
return function(string) {
return adjective + ' ' + string;
}
}

var coolifier = makeAdjectifier('cool');
coolifier('conference')

Don’t iterate

use map, reduce, filter
将函数提供给高阶函数得到想要的数据

for while do-while

Avoid mutability

use immutable data

有时会意想不到的改变某些而导致的 bug。更好的方法就是将所有数据视为不可变的,永不改变。

1
2
3
4
5
6
7
8
9
10
11
12
// Mutation
var rooms = ['H1', 'H2', 'H3']
rooms[2] = 'h4'

// No mutation
var rooms = ['H1', 'H2', 'H3']
var newRooms = rooms.map(function (rm){
if (rm === 'H3') {
return 'H4'
}
return rm
})

不变性的问题在于,把数组和对象视为不可变的,每当需要进行一个小调整,先复制再修改。

持久化数据结构


更改一小部分,重用旧的结构。结构共享,可以在新旧数据中共享某些部分。有更高的效率进行添加/修改。

  • immutable.js

Q&Q

面向对象 VS 函数式编程
编程范式的哲学,没有一个范式比其他更好或更糟。
他们只是有不同的优点/缺点,和不同适用的情况,他们将成为最佳工具来解决某些问题。
如果你想快速地编写脚本就在你电脑上很快的运行一次,那么以命令式进行操作也是完全合法的.

取决于实际情况