与指令编程相比,函数式编程就是考虑利用已有的函数去解决问题。指令编程是根据基础步骤一步步完成。
函数编程是不同逻辑的组合,指令编程是利用最基础的API一点点组合。
概念理解总体来说就是:
- 代码函数组合
- 目的封装组合复用
- 函数逻辑而非过程逻辑
函数式编程的几大特点
1. 函数式编程是一等公民
所谓一等公民就是说跟基础的数据类型同等地位。
2. 只用"表达式",不用"语句"
表达式就是说单纯运算,返回结果。语句是执行步骤。类似加法和计算1+1等于几的区别。
3.没有"副作用"
内部计算,不对外不产生影响。
4.不修改状态
变量不可改变,没有状态改变和中间值。递归函数中只返回不改变变量值,使用参数承载。没有状态管理危机。
5.引用透明
输入值计算出唯一输出
柯里化
返回函数
function fun(param1){
return function(param2){
return param1+param2
}
}
简化参数
function getTotalUrl(protocol){
return function(hostname,path){
return protocol + hostname + path
}
}
const getUrl = getTotalUrl("https://");
const url1 = getUrl("baidu.com","/知道")
const url2 = getUrl("baidu.com","/问答")
动态创建函数
//listener: 回调函数 useCapture: 冒泡
const whichEvent = ( function(){
if( window.addEventListener ){
return function (element, type, listener, useCapture){
element.addEventListener(type,function(e){
listener.call(element,e)
},useCapture)
}
}else if( window.attachEvent ){
return function (element, type, handler){
element.attachEvent("on"+type,function(e){
handler.call(element,e)
})
}
}
})()
延迟执行
arguments:函数开始后产生的类数组, arguments.length为函数实参个数,arguments.callee引用函数自身。Array.prototype.slice.call( arguments )继承函数的方法。
add(1)(2)
add(1,2,3)(3)
add(1,2,3)(3)(4)
柯里化+递归
//写法1
function add(){
let args = Array.prototype.slice.call( arguments );
let inner = function(){
args.push(...arguments)
return inner
}
inner.toString = function (){
return args.reduce(function(pre,cur){
return pre + cur
})
}
return inner
}
//写法2
function currying(func) {
const args = [];
return function result(...rest) {
if (rest.length === 0)
return func(...args);
args.push(...rest);
return result;
}
}
const add = (...args) => args.reduce((a, b) => a + b);
const sum = currying(add);
//柯里化函数进一步抽象
function currying(fn, length) {
length = length || fn.length
return function (...args) {
return args.length >= length? fn.apply(this, args) : currying(fn.bind(this, ...args), length - args.length)
}
}
const add = currying((...args) => args.reduce((a, b) => a + b))
网友评论