25_闭包节流防抖
五、闭包
什么是闭包
在函数内部能够读取到其他函数内部的变量
通俗的说:闭包就是函数套函数,一个内部函数引用了外部函数的变量,外部函数形成了一个闭包
认识闭包
典型应用:函数套函数 返回值是内部的函数
function fn(){
var a = 10;
function test(){
a++;
// 内部函数使用a的时候,先在自身作用域去找,如果没有就去上一级作用域去找,
// 这样的查找机制叫“作用域链”
console.log(a);//10
}
return test;
}
let resFn = fn();
resFn();
resFn();
resFn();
function box(){
// 在函数内部定义了b变量,
// 在函数执行完毕之后,b没用了,就会把它当成垃圾回收掉
// 所以外部的b 已经被回收掉了
var b = 11;
}
box()
console.log(b);
// 垃圾回收机制:怎么认定是不是垃圾 改不改被回收??
// 标记清除法(js采用-能从全局引用到的变量 都不会被回收)
// 闭包的作用:让局部变量常驻内存
六、防抖和节流
防抖
防止一段代码或者函数 短时间内多次被执行
防抖是 只执行最后那一次,
借助延时器实现
var timer;
window.onresize = function(){
// resize 事件多次触发,每次都会调用change函数
// 永远先清除上一次的延时器 --启动一个新的延时器
// 到最后 窗口大小不改变了,不清除了,延时1秒 自动的执行change函数
clearTimeout(timer)
timer = setTimeout(()=>{
change()
},1000)
}
function change(){
console.log("窗口大小变化了");
}
防抖的封装
window.onresize = function () {
// resize 事件多次触发,每次都会调用change函数
// 永远先清除上一次的延时器 --启动一个新的延时器
// 到最后 窗口大小不改变了,不清除了,延时1秒 自动的执行change函数
// 触发 处理完防抖之后的函数即可
resFn();
}
function change() {
console.log("窗口大小变化了");
}
let resFn = debounce(change, 1000);
// 要封装一个防抖的函数,,防抖 让哪个函数防抖 change
function debounce(fn, interval) {
var timer;
// 防抖通过延时器实现
return function () {
clearTimeout(timer)
timer = setTimeout(() => {
fn()
}, interval)
}
}
节流
节流就是一段代码或函数 短时间内被多次执行,我们可以让它有规律的执行,
比如 fn函数一秒钟执行了10次, 通过节流让fn函数 一秒钟执行1次
需求:当用户输入的时候,想要获取输入框的值, 然后执行一个函数检查用户的输入
如果用户输入的太快,那么我可以每秒钟检查一次
<input type="text">
<script>
var ipt = document.querySelector("input");
var flag = false; //记录是否在等待执行getval false 不等待马上执行 true 等待
// 每1秒钟 获取一次value值
// 分成两种情况
// 如果是在1秒钟之内不断的输入 需要节流 等待执行getval
// 反之 不需要
ipt.oninput= function(){
if(flag==true){
console.log("正在等待");
}else{
// 不等待 马上执行
// 第一次触发这个函数,触发之后还是频繁的输入 就该等待了
// 所以 flag 的值改成true
getval()
flag = true
setTimeout(()=>{
flag = false
console.log("等待结束");
},1000)
}
}
function getval(){
console.log("获取value值");
}
</script>
封装节流
var ipt = document.querySelector("input");
// 每1秒钟 获取一次value值
// 分成两种情况
// 如果是在1秒钟之内不断的输入 需要节流 等待执行getval
// 反之 不需要
ipt.oninput = function () {
newFn()
}
function getval() {
console.log("获取value值");
}
let newFn = throttle(getval,1000);
// 封装节流功能
// 需要让谁节流
function throttle(fn, interval) {
var flag = false; //记录是否在等待执行getval false 不等待马上执行 true 等待
return function () {
if (flag == true) {
console.log("正在等待");
} else {
// 不等待 马上执行
// 第一次触发这个函数,触发之后还是频繁的输入 就该等待了
// 所以 flag 的值改成true
fn()
flag = true
setTimeout(() => {
flag = false
console.log("等待结束");
}, 1000)
}
}
}