作用域、闭包、防抖节流
作用域
image.png如何理解闭包
- 函数执行形成不销毁的私有作用域,它可以保护里面的私有变量不受外界干扰,而且还可以保存值,这种机制就是闭包机制
- 不销毁的条件:函数返回一个引用数据类型的值,而且这个值得被外界接收
- 不过
闭包比较耗性能,占内存。
有了es6之后,虽然es6原理也是副作用域和每一个循环的块作用域,跟闭包原理一样,但毕竟是内置的,所以性能要比闭包好一点,后来我们就用es6。 - 闭包举例:防抖、节流
- 防抖:就是在指定的时间内只能触发一次,即最后一次才执行,经常用于搜索框。当前函数执行的时候会把上一次的定时器清空,然后在开一个定时器
- 节流:每隔一段时间执行一次,稀释执行的频率 window.onscroll。让本次执行的时间减去上次执行的时间,如果它们的差值大于规定的时间,就执行函数,如果不大于就不执行。【一段时间内,只做一件事情】
防抖节流
参考https://segmentfault.com/a/1190000018428170
防抖
- 防抖:就是在指定的时间内只能触发一次,即最后一次才执行,经常用于搜索框。当前函数执行的时候会把上一次的定时器清空,然后在开一个定时器
function debounce(fn,delay){
let timer = null //借助闭包
return function() {
if(timer){
clearTimeout(timer)
}
timer = setTimeout(fn,delay) // 简化写法
}
}
// 然后是旧代码
function showTop () {
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
}
window.onscroll = debounce(showTop,1000) // 为了方便观察效果我们取个大点的间断值,实际使用根据需要来配置
image.png
image.png
节流
- 节流:每隔一段时间执行一次,稀释执行的频率 window.onscroll。让本次执行的时间减去上次执行的时间,如果它们的差值大于规定的时间,就执行函数,如果不大于就不执行。【一段时间内,只做一件事情】
function throttle(fn,delay){
let valid = true
return function() {
if(!valid){
//休息时间 暂不接客
return false
}
// 工作时间,执行函数并且在间隔期内把状态位设为无效
valid = false
setTimeout(() => {
fn()
valid = true;
}, delay)
}
}
/* 请注意,节流函数并不止上面这种实现方案,
例如可以完全不借助setTimeout,可以把状态位换成时间戳,然后利用时间戳差值是否大于指定间隔时间来做判定。
也可以直接将setTimeout的返回的标记当做判断条件-判断当前定时器是否存在,如果存在表示还在冷却,并且在执行fn之后消除定时器表示激活,原理都一样
*/
// 以下照旧
function showTop () {
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
}
window.onscroll = throttle(showTop,1000)
image.png
网友评论