这篇文章的目的并不是说一种范式比另一种范式更好。它只是显示您遇到的常见模式及其同等的函数实现方法。(banq注:其实对使用Java Stream替代if/else也有参考作用)
if / else
命令范式:
const hour = 14 let greeting
if (hour < 18) { greeting = 'Good day'; } else { greeting = 'Good evening'; }
|
函数范式:
if语句可以被函数getGreeting替代,从而重用:
const isDay = hour => hour < 18 const getGreeting = hour => isDay(hour) ? 'Good Day' : 'Good Evening' const greeting = getGreeting (hour)
|
if (无else)
命令范式:
let name = 'joel' if (name != null) { name = name.toUpperCase() }
|
函数范式:
isNotnull和toUpperCase市可重用的函数:
import when from 'mojiscript/logic/when'
const isNotNull = obj => obj != null const toUpperCase = when (isNotNull) (string => string.toUpperCase ())
const name = 'joel' const upperName = toUpperCase (name)
|
数组相加
命令范式:
const values = [1, 2, 3]
let sum = 0 for (const x of values) { sum = sum + x }
函数范式: 不将sum变成可变变量:
|
const values = [1, 2, 3]
const add = (x, y) => x + y const sum = values.reduce(add)
|
命令范式:
const values = [1, 2, 3, 4, 5]
let evens = for (const x of values) { if (x % 2 === 0) { evens.push(x) } }
|
函数范式:
不要将evens成为可变:
import filter from 'mojiscript/list/filter'
const values = [1, 2, 3, 4, 5]
const isEven = num => num % 2 === 0 const evens = filter (isEven) (values)
|
提前中断循环
命令范式:
const values = [1, 2, 3] let sum = 0 for (const x of values) { if (x > 3) break sum = sum + x }
|
函数范式:
使用reduceWhile,类似reduce,能接受一个predicate提早结束。
import reduceWhile from 'mojiscript/list/reduceWhile'
const add = x => y => x + y const lte3 = num => num <= 3
const sum = reduceWhile (() => lte3) (add) (0) (values)
|
if / else if / else
命令范式:
const fn = temp => { if (temp === 0) return 'water freezes at 0°C' else if (temp === 100) return 'water boils at 100°C' else return `nothing special happens at ${temp}°C` }
fn(0) //=> 'water freezes at 0°C' fn(50) //=> 'nothing special happens at 50°C' fn(100) //=> 'water boils at 100°C'
|
函数范式:
import cond from 'mojiscript/logic/cond' import $ from 'mojiscript/string/template'
const fn = cond([ [0, 'water freezes at 0°C'], [100, 'water boils at 100°C'], [() => true, $`nothing special happens at ${0}°C`] ])
fn(0) //=> 'water freezes at 0°C' fn(50) //=> 'nothing special happens at 50°C' fn(100) //=> 'water boils at 100°C'
|
类
命令范式:
class Cat { constructor() { this.sound = 'Meow' }
talk() { return this.sound } }
const cat = new Cat() const talk = cat.talk
cat.talk() //=> 'Meow' talk() //=> Error: Cannot read property 'sound' of undefined
|
函数范式:
const cat = { sound: 'Meow' }
const dog = { sound: 'Woof' }
const talk = animal => animal.sound
talk (cat) //=> 'Meow' talk (dog) //=> 'Woof'
|
检查空NULL
命令范式:
const toUpper = string => { if (string != null) { return string.toUpperCase() } }
|
函数范式:
此示例将参数包装在一个
类型中,然后在最后将其解包。在一般FP应用程序中,可在整个应用程序使用Maybe,不需要打包和解包string。所以这比你通常看到的要冗长一些。import S from 'sanctuary'
const toUpper = S.pipe ([ S.toMaybe, S.map (string => string.toUpperCase ()), S.maybeToNullable ])
// If you use `Maybe` throughout your app, this would be your `toUpper` function. const toUpper = S.map (string => string.toUpperCase ());
|