18、经典函数题
请实现一个函数满足以下功能
add(1) //1
add(1)(2) //3
add(1)(2)(3) //6
add(1)(2,3) //6
add(1,2)(3) //6
add(1,2,3) //6
函数柯里化,利用闭包的保存的特性,实现预先处理的方法
function currying(fn,len){ //可执行多少次
len = len||fn.length; //函数的length是获取函数的形参个数
return function(...args){
if(arg.length>=len){
return fn(...args) //如果执行次数小于等于这个参数个数;直接执行这个方法
}
//不直接执行,二十返回一个可以继续执行的函数;args将这次的参数当作参数传入下面执行的方法中
return currying(fn.bind(null,...args,len-arg.len))
}
}
let add = currying((...args)=>{
eval(arg.join('+'))
},4) //也就是可执行多少次,所有的传入参数的个数
add = currying(add,4)
add(1)(2)(3)(4) //10
add(1)(2,3)(4) //10
add(1,2)(3)(4) //10
add(1,2,3,4) //10
函数柯里化:函数预先处理,利用闭包。例如:bind
let obj = {
name:'OBJ'
}
function fn(...arg){
console.log(this,arg)
}
document.body.onclick = fn; //this 为 BODY
document.body.onclick = function(ev){
//ev事件对象:给元素的某个事件绑定方法,当事件触发会执行这个方法,并且会把当前事件的信息传递给这个函数的"事件对象"
}
//要求:给fn中的this指向obj并且传入100,200,以及事件对象(预先处理思想)
//1、使用bind
document.body.onclick = fn.bind(obj,100,200);
//2、自己写:执行匿名函数
document.body.onclick = function(ev){
fn.call(obj,ev,100,200)
}
自定义mybind实现
let obj = {
name:'OBJ'
}
(function(){
mybind(context=window,...outerArg){
let _this = this;
//this 指向fn
return function(...innerArg){
//此时这个匿名函数中的this指向BODY
_this.call(context,...outer,...innnerArg)
}
}
Function.prototype.mybind = mybind;
})()
fn.mybind(obj,100,200)
函数柯里化:返回一个匿名函数,形成闭包,保存第一次执行传入的参数,并返回一个函数。第二次执行的时候直接使用上一次保存的数据,供调用。利用闭包的保存作用。
闭包两大作用:保护、保存