函数柯里化: 预先处理思想(利用闭包机制)
将要使用到的数据存入闭包,要用到的使用从闭包当中找
// 简单例子
// function fn(x) {
// //会预先将x存入闭包
// return function (y) {
// return x+y
// }
// }
// fn(100)(200)
// 实现bind方法
// 思想: 执行bind方法,会返回一个匿名函数
(function () {
// context=window: 传入的函数,没有传入默认是window
// ...outerArg: 传入参数
function myBind(context=window, ...outerArg) {
// this: 需要改变this指向的函数
// context: 需要改变的this指向
// outerArg: 其余需要传递给函数的实参
let _this = this //fn1
return function (...innerArg) {
_this.call(context, ...outerArg.concat(innerArg))
}
}
Function.prototype.myBind = myBind
})()
var obj = {
name: 'yueyue'
}
function fn1 (...arg) {
console.log(this, arg) //this=>body arg: [事件对象]
}
// 使用bind方法
document.body.onclick = fn1.myBind(obj, 100, 200, 300)
//需求: 点击的时候把fn1中的this=>obj, arg=>[100, 200, 事件对象]
//不使用call或apply是因为他们是立即执行,把需求当中是要点击的时候才触发
// document.body.onclick = fn1.bind(obj, 100, 200)
// // 相当于
// document.body.onclick = function(ev) {
// fn1.call(obj, 100, 200, ev)
// }
// 结论: 执行bind方法,会返回一个匿名函数
// document.body.onclick = fn1
// document.body.onclick = function (ev) {
// //ev是事件对象:给元素的某个事件绑定方法,当事件触发会执行这个方法,并且会把当前事件的相关信息
// //传递给这个这个函数的事件对象
// console.log(ev) //ev是事件对象
// }
题目:
请实现一个add函数,满足以下功能
add(1) //1
add(1, 2) //3
add(1)(2)(3) //6
add(1)(2)(3)(4) //10
add(1)(2,3) //6
add(1,2)(3) //6
add(1,2,3) //6
function currying(fn, length) {
length = length || fn.length //不给length,默认为函数的参数长度
return function(...args){
if(args.length >= length) {
return fn(...args)
}
return currying(fn.bind(null, ...args), length - args.length)
}
}
function add(n1, n2, n3, n4) {
return n1 + n2 + n3 + n4
}
add = currying(add, 4) //4:控制4个数相加
// 或者
// let add = currying((...arg) => eval(arg.join('+')), 4)
console.log(add(1)(2)(3)(4)) //10 图解
console.log(add(1,2)(3,4)) //10 图解
console.log(add(1,2,3,4)) //10
图解:
1.add(1)(2)(3)(4)
2.add(1,2)(3,4)