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)

函数柯里化:返回一个匿名函数,形成闭包,保存第一次执行传入的参数,并返回一个函数。第二次执行的时候直接使用上一次保存的数据,供调用。利用闭包的保存作用。

闭包两大作用:保护、保存

results matching ""

    No results matching ""