浅谈闭包(防抖,节流,函数柯里化)
闭包参考文章
谈谈你对闭包的理解
概念:
(1) 闭包就是引用了另一个函数的变量的函数
(2) 闭包一般是函数嵌套,一个函数返回另外一个函数,内部函数访问外部函数的变量就形成了一个闭包
作用(优点):
(3) 闭包的优点是可以私有化变量,将变量私有化到函数内部,并在私有化的基础上进行数据保持
用途:
(4) 闭包在防抖节流函数柯里化,都应用里数据保持这个特性
(5) 在防抖函数中,第一次点击的时候,我们会let一个time一个定时器,如果不采用闭包的话,下次触发函数会重新创建一个新的定时器,两个定时器的引用不同,是没有关联的,使用闭包可以直接在内存中找到之前创建的计时器,调用就可以直接拿到对应的定时器的时间
缺点:
(6) 闭包的缺点是容易造成内存泄露,因为闭包创建的变量会一直存在内存中,需要及时置空,否则会造成内存泄露,影响程序性能
清除闭包,使闭包函数等于null,例如debounce=null
闭包注意两点:
- 闭包不一定有return
- 闭包也不一定有内存泄漏
//防抖
function debounce(fn,delay){
let timer = null
return function(){
// 如果存在点击事件就清除,第一次肯定不存在,执行定时器,正在执行的时候下一个请求进来,就关闭上个,继续下一个定时器
if(timer){
clearTimeout(timer)
}
timer = setTimeout(fn,delay)
}
}
// 节流
function thorate(fn,delay){
var valid = true
return function(){
if(!valid ){
return false
}
valid = false
// 一段时间之后再调起函数
let timer = setTimeout(()=>{
fn();
valid = true
},delay)
}
}
// 函数柯里化
function sum(args) {
return args.reduce((pre, cur) => pre + cur, 0)
}
function curry(...args) {
let sumVal = sum(args)
return function calc(...newArgs) {
if (newArgs.length > 0) {
console.log(newArgs);
sumVal += sum(newArgs)
return calc
} else {
return sumVal
}
}
}
console.log(curry(1)(1)(10)());
// 针对函数参数进行优化
function uri_curry(protocol){
return function (hostname,pathname){
return `${protocol}${hostname}${pathname}`
}
}
const uri_https = uri_curry('https://')
const uri1 = uri_https('www.baidu.com','/真棒')
const uri2 = uri_https('www.baidu.com','/加油')
console.log(uri1,uri2);
tips:
函数柯里化:
针对函数参数进行优化
官方解释:
柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。
简单来说,就是固定一个需要多个参数的函数的部分参数,返回一个接受剩余参数的函数,当然这个转化流程需要固定多少个参数,返回的函数需要接收多少个参数,这都是有开发者自己定义的,当然,这两个的个数相加会等于这个函数原始情况需要的参数个数。
reduce()
定义一个相加 reduce()
方法是JavaScript中的一个内置方法,主要用于对数据进行归并操作。它通常用于计算数组中所有元素的和。
具体来说,reduce()
方法会遍历数组的每一个元素,并将这些元素传递给用户提供的回调函数。该回调函数接受四个参数:前一个值、当前项、当前项的索引以及整个数组的引用。函数的返回值将作为下一个遍历过程中的输入值。
此外,reduce()
方法需要传入第二个参数,即归并计算的初始值