什么是函数式编程
函数式编程(functional programing)是编程范式之一。我们常见的范式还有面向过程、面向行为、面向对象等。
纯函数
- 相同的输入会得到相同的输出,而且没有任何可观测的副作用。
// 可以做缓存
function memoize (fn) {
const obj = {}
return function (...args) {
const key = args.join('-')
if(obj.hasOwnProperty(key)) {
return obj[key]
}
const result = fn(...args)
obj[key] = result
return result
}
}
闭包
当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用
域之外执行。
- 缓存 上面缓存的方法就是用到了闭包
- 模块化
// 模块化
(function(win) {
var obj = {}
win.define = function (key, fn) {
obj[key] = fn()
}
win.require = function (key, fn) {
fn(obj[key])
}
})(window)
define('q', function(){
return {
log: console.log
}
})
require('q', function(q) {
q.log(123)
})
高阶函数
参数是一个函数,会返回一个新函数
curry,compose,memoize都是高阶函数
柯里化
function add (a, b, c, d) {
return a + b + c + d
}
function curry (fn, ...args) {
return function(...rest) {
const params = [...args, ...rest]
return params.length >= fn.length
? fn.apply(fn, params)
: curry.call(curry, fn, ...params)
}
}
const newAdd = curry(add)
newAdd(1)(2)(4)(3) // 10
newAdd(1, 2, 3, 4) // 10
newAdd(1, 2, 3)(4) // 10
- curry是一个高阶函数
- 对函数进行改造,可以传入部分参数返回一个新函数,等待剩余参数传入最后执行。
函数组合
function add2 (num) {
return num + 2
}
function multiply2 (num) {
return num * 2
}
function del2 (num) {
return num - 2
}
function compose (...fns) {
return function (...args) {
return fns.reverse().reduce(function (a, b) {
return typeof a === 'function' ? b(a(...args)) : b(a)
})
}
}
const newFn = compose(
del2,
multiply2,
add2
)
newFn(10) // 22
- compose是一个高阶函数
- 将多个函数组合成一个新函数,一般是从右向作执行
- 参数中除了第一个执行的方法,别的方法只能接受一个参数,这个时候就需要使用柯里化来配合
函子
一个容器(用一个普通对象来实现),包含了任意类型的值,这个对象具有map方法,用来操作里面的值。一般也具有一个of方法,来代替new完成实例化。
del2(multiply2(add2(10)))
compose(
del2,
multiply2,
add2
)(10)
// 在函数式编程的思维中期望这样实现
Functor.of(10).map(add2).map(multiply2).map(del2)
function Functor(val){
this.val = val;
}
Functor.prototype.map=function(fn){
return new Functor(fn(this.val))
}
Functor.of = function(val) {
return new Functor(val)
}
// Functor就是一个函子
网友评论