注:学习函数柯里化的笔记
推荐学习视频:3_手写柯里化函数_哔哩哔哩_bilibili
一、柯里化定义
Currying
把 接受多个参数的函数 变换为 接受一个单一参数(最初函数的第一个参数) 的 函数,并且 返回 接受余下的参数的新函数 的技术。
二、柯里化的好处
好处:1)参数复用(利用了闭包 和 高阶函数的特性)
2)做代码的延迟执行(eg:bind方法的实现机制)
1.参数复用:可以 复用第一个(第一次的)参数(闭包机制),改变后面的参数
eg1:
// eg:闭包特性:将第一次(前面)传递的参数:1 ,先保存下来
let _add = add(1)
_add(2, 3, 4)// 1+2+3+4
_add(7, 8, 9) //1+7+8+9
eg2:
// eg: 正则校验:柯里化
function check(reg) {
return function(str) {
return reg.test(str)
}
}
let hasNum = check(/\d+/)
console.log(hasNum('567'))//true
console.log(hasNum('asd'))//false
2. 延迟执行:bind函数及使用
三、性能
创建大量嵌套作用域和闭包函数会带来花销,无论是在内存还是速度上,
其实在大部分应用中,主要的性能瓶颈是在操作dom节点上,这js的性能损耗基本可以忽略不计,可以放心使用柯里化。
四、实现一个通用的柯里化函数
// 实现一个通用的柯里化函数
function curry(fn,...args) {
// 判断fn参数是否足够,
// 足够 => 直接执行fn,并返回结果
// 否则拼接参数,直至fn参数足够=> 直接执行fn,并返回结果(递归)
// fn.length属性记录的该函数所需参数的个数
if (args.length >= fn.length) {
return fn(...args)
}
// 递归调用
return function(...args1) {
return curry(fn,...args,...args1)
}
}
let addF = (x, y, z) => x + y + z
let curryAddF = curry(addF)
console.log(curryAddF(1)(2)(3)) // 6
五、常见面试题:不定长参数的add方法
1.使用ES6语法:...
// 简单应用:参数复用
// 实现add(1)(2)(3)(4) = 10 add(1)(1,2,3)(2) = 9
// 将一个接受多个参数的函数 变为 接受一个参数 返回一个函数的形式
// 实现思路:闭包 重要作用:延迟处理
// arguments
// ES6展开
function add(...args) {
let arr = [...args]
console.log(arr)
let addFun = function(...args1) {
arr.push(...args1)
console.log(arr)
// 递归实现
return addFun
}
// toString 有隐式调用的效果
// 原本的函数 在返回时 被隐式转换成了字符串
addFun.toString = function() {
// 累加
return arr.reduce((preR, item) => {
return preR + item
},0)
}
return addFun
}
console.log(+add(1)(2,3)(4,5)) // 15
2.使用arguments
// arguments
function add1() {
let arr = Array.prototype.slice.call(arguments)
// console.log(arr)//[1]
let a2 = function() {
let temp = Array.prototype.slice.call(arguments)
arr = arr.concat(temp)
return a2
}
a2.toString = function() {
return arr.reduce((pre,cur) => {
return pre + cur
},0)
}
return a2
}
console.log(+add1(1)(2,3)(4,5)) // 15
注意点:
1.函数柯里化的定义及好处的理解;
2.递归
3.闭包
4.数组方法:push + Array.prototype.slice.call(arguments) + reduce
5.toString隐式调用:add(1)(2)=>function addFun(){}====>字符串形式展示?
=>typeof XX =>function
+add(1)(2)=>3