问题引出:频繁调用函数造成性能浪费
当一个函数无意义的高频率调用时,需要设置函数函数防抖和函数节流,限制这种无意义的调用,通过调用次数的减少来提高代码性能
问题场景:搜索框实时发请求,onmousemove, resize, onscroll等等
1.input搜索框内容的输入:用户敲击键盘的时候去触发一个函数
2 resize,变化浏览器的大小,控制台会一直打印
3.拖动滚动条,会持续触发onscroll监听事件
4.鼠标移动事件中不断返回鼠标经过的位置
解决方法:函数防抖和函数节流
思路:不影响使用的情况下,适度降低函数的触发频率
函数防抖(debounce):触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间。
函数节流(throttle):限制一个函数在一定时间内只能执行一次
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<title>函数防抖和函数节流</title>
<style>
#box {
width: 600px;
height: 200px;
background: pink;
margin: 0 auto;
text-align: center;
line-height: 200px;
font-size: 50px;
color: red;
}
</style>
</head>
<body>
<div id="box"></div>
</body>
<script>
var box = document.getElementById("box");
var n = 1;
function count() {box.innerHTML = n++;}
//1.调用防抖函数
// box.addEventListener("mousemove", debounce(count, 1000));
//2.调用节流函数
box.addEventListener("mousemove", throttle(count, 1000));
</script>
</html>

2.函数防抖
// 函数防抖-实现思路:通过闭包封装定时器,使得定时器只在最后一次触发时执行
// 闭包起到的作用:使得定时器只在最后一次触发时执行
// 闭包step1:外层函数包裹内层函数
function debounce(fn, delay) {
var timer = null; // 定时器
// 闭包step2:外层函数内return内层函数
return function(){
if(timer) clearTimeout(timer); // 清除定时器
// 闭包step3:内层函数调用外层函数的参数
timer=setTimeout(()=>{
console.log("定时器执行了...");
fn.apply(this,arguments)//执行函数:apply改变this指向,arguments接收参数,this从指向事件监听器变成了指向内层函数
},delay)
}
}
3.函数节流
// 函数节流-实现思路:通过闭包封装定时器,使得定时器只在第一次触发时执行
// 闭包step1:外层函数包裹内层函数
function throttle(fn, delay) {
var timer = null; // 定时器
// 闭包step2:外层函数内return内层函数
return function (){
// 闭包step3:内层函数调用外层函数的参数
if(Date.now()-timer>delay){// 时间戳差值大于延迟时间,则执行函数
timer=Date.now(); // 更新时间戳
fn.apply(this,arguments)//执行函数:apply改变this指向,arguments接收参数,this从指向事件监听器变成了指向内层函数
}
}
}
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 100%;
height: 300px;
font-size: 100px;
font-weight: 900;
text-align: center;
line-height: 300px;
background: pink;
color: red;
}
</style>
</head>
<body>
<div></div>
</body>
<script>
var div = document.querySelector("div");
var i = 0;
div.innerHTML = i;
// 鼠标移动就触发
function count() {
div.innerHTML = i++;
}
/******函数防抖:一定时间内只触发一次,若在此期间内再次触发则重新计时******/
// function debounce(fn, delay) {
// var timer = null;
// return function() {
// if (timer) clearInterval(timer);
// timer = setTimeout(() => {
// fn.bind(this, arguments)()
// }, delay);
// }
// }
// div.addEventListener("mousemove", debounce(count, 1000));
/******函数节流:一定时间内只触发一次******/
function throttle(fn, delay) {
var timer = null;
return function() {
if (Date.now() - timer > delay) {
fn.bind(this, arguments)();
timer = Date.now();
}
}
}
addEventListener("mousemove", throttle(count, 1000));
</script>
</html>
防抖和节流使用到的知识点
- 闭包
- bind,call,apply修改this指向

本文探讨了如何通过函数防抖和节流技术优化代码性能,特别是在搜索框实时请求、浏览器resize事件、onscroll监听以及鼠标move事件等场景下。文章提供了防抖和节流的实现代码,并指出这两种技术可以有效减少无意义的函数调用,提高网站性能。同时,这些优化策略也是面试中常见的技术问题,体现了开发者对项目性能的关注和优化能力。
1928

被折叠的 条评论
为什么被折叠?



