函数式编程(一)

函数式语言给了我一个全新的视角,从一个完全不同的方式去看待编程,开始会感到不自然,需要时间去适应。所有的定义都是基于函数,值不可更改,无状态,但是时间久了就会发现代码会更加简洁,而且容易复用。

if 简化

几乎每个if语句的实例都可以用一个等价的三元操作来替代。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 典型的
function saveCustomer(customer) {
if (isCustomerValid(customer)) {
database.save(customer)
} else {
alert('customer is invalid')
}
}
// 三元
function saveCustomer(customer) {
return isCustomerValid(customer)
? database.save(customer)
: alert('customer is invalid')
}
// ES6 的写法
const saveCustomer = customer =>
isCustomerValid(customer)
? database.save(customer)
: alert('customer is invalid')

多层嵌套

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 多层 else-if
function customerValidation(customer) {
if (!customer.email) {
return error('email is require')
} else if (!customer.login) {
return error('login is required')
} else if (!customer.name) {
return error('name is required')
} else {
return customer
}
}

// ES6 三元修正
const customerValidation = customer =>
!customer.email ? error('email is required')
: !customer.login ? error('login is required')
: !customer.name ? error('name is required')
: customer

现在就可以清楚地看到左侧定义的所有条件以及右侧返回的值。

没有 for 循环

filter, map 和 reduce 可以满足所有情况, filter、map 和 reduce 共同点就是并不会对原数组做任何改动,结果都是生成一个新变量。

原始代码 获得小于 10个月的

1
2
3
4
5
6
7
8
9
10
11
12
const peoples = [
{ name: '小明', months: 84 },
{ name: '小小明', months: 24 },
{ name: '小小小明', months: 4 }
]
var children = []
for (var i = 0; i < peoples.length; i++) {
if (peoples[i].months < 10) {
children.push(peoples[i].name)
}
}
console.log(children)

将 if 语句提取到它自己的函数中

1
2
3
4
5
6
7
const isChildren = people => people.months < 10
var children = []
for (var i = 0; i < peoples.length; i++) {
if (isChildren(peoples[i])) {
children.push(peoples[i].name)
}
}

下一个改变是从 people 类型的对象中提取转换(或映射)到名称。

1
2
3
4
5
6
7
8
const isChildren = people => people.months < 10
const getName = people => people.name
var children = []
for (var i = 0; i < peoples.length; i++) {
if (isChildren(peoples[i])) {
children.push(getName(peoples[i]))
}
}

最后一步 使用 map 操作,最好地展示您的代码的可读性

1
2
3
4
5
const isChildren = people => people.months < 10
const getName = people => people.name
const children =
peoples.filter(isChildren)
.map(getName)

完成

1
2
3
4
5
6
7
8
9
10
11
12
const isChildren = people => people.months < 10
const getName = people => people.name
const getChildrenNames = peoples =>
peoples.filter(isChildren)
.map(getName)
const peoples = [
{ name: '小明', months: 84 },
{ name: '小小明', months: 24 },
{ name: '小小小明', months: 4 }
]
const children = getChildrenNames(peoples)
console.log(children)