文章目录
一、闭包是什么?
1、闭包定义:
一个函数对另一个函数中的变量进行了引用
2、闭包的特点:
1、函数嵌套函数 2、外部函数访问了内部函数的变量
3、闭包的本质:
函数执行在执行栈上,执行完毕后从执行栈移除,内部成员的内存被释放,但是如果外部对内部成员进行了引用,则内部成员的内存不能被释放
执行栈:用来存储代码运行时创建的所有执行上下文的容器
执行上下文:执行 JavaScript 代码的环境,Javascript 代码都是在执行上下文中运行
4、闭包的作用:
1、可以延伸变量的作用范围 2、定时器传参 3、避免全局变量污染5、闭包的缺点:
闭包会常驻内存,会增大内存的使用量,使用不当会导致内存泄露,在使用完闭包,要及时清除二、闭包实现防抖、节流、柯里化
1.防抖
定义:
当事件被触发时,延迟n秒执行其回调,在此期间事件又被触发,则重新计时
实现思路:
根据定义,我们可以通过开启一个延时器,将需要执行防抖的事件放入这个延时器中,通过闭包来将这个延时器缓存起来,每次触发该延时器之前都会清空上一次的延时器,所以只要时间没到规定的时间就会重新计时
代码实现:
function debounce(fn, delay) {
var timer = null
return function () {
//清楚上一次定时器
clearTimeout(timer)
timer = setTimeout(() => {
//这里需要用箭头函数,来继承上一级执行上下文中的this
//改变this指向,因为fn()单独调用this指向window
fn.call(this)
}, delay)
}
}
document.documentElement.onclick = debounce(function () {
console.log('document被点击了');
}, 1000)
2.节流
定义:
在规定的时间内,事件只被允许触发一次
实现思路:
根据定义,我们可以记录一个起始时间戳,通过闭包将该时间戳缓存起来,每次我们触发需要节流的事件,也会定义一个时间戳,让当前的时间戳与起始时间戳进行相减来与规定的时间进行比较,如果时间小于规定时间就不会继续执行该事件,大于的就再次执行该事件
代码实现:
function throttle(fn, delay) {
// fn 要执行的回调 delay规定的时间
var lastTime = 0
return function () {
var nowTime = Date.now(); //当前的时间戳
if (nowTime - lastTime > delay) {
fn.call(this)
// 同步时间
lastTime = nowTime
}
}
}
document.body.onclick=throttle((function(){
console.log('document被点击了');
}),500)
3.柯里化
定义:
被柯里化函数包裹的函数就会具备一种能够缓存参数的能力,这样就能实现调用该函数的时候可以分别传参
实现思路:
根据定义,我们可以知道柯里化函数是接受一个函数作为参数,当传递进来函数的参数大于或等于所需要的参数时,直接返回结果,少于的话就返回一个柯里化函数
代码实现:
var curry = function (fn) {
// 收集fn参数的个数
var limit = fn.length
// 定义个空数组来收集每次传过来的参数
var params = []
// 判断传过来的参数是否等于所需要的参数
return function _curry(...args) {
// 剩余参数:ES6允许在不知道有多少个参数时用剩余参数表示为一个数组
params = params.concat(args)
if (limit <= params.length) {
// 当传递进来的参数大于或等于所需要的参数时,直接返回结果
return fn.apply(null, params)
} else {
// 少于的话就返回一个_curry函数
return _curry
}
}
}
总结
以上就是今天要讲的内容,本文仅仅简单介绍了闭包,以及通过闭包实现防抖、节流、柯里化。第一次写博客,这些知识点是我在学习过程中总结的,我觉得这样理解应该是对的,轻点喷。。。