该题考察的是性能,体验优化方案,闭包。
防抖:时间被连续触发的情况下,只执行最后一次的事件
节流:时间间隔相等的(频率不变)的执行被频繁触发的事件。
防抖
核心思想:触发事件后,函数不会立即执行,而是等待一段时间(比如 n 秒)。
如果在这段时间内再次触发事件,则重新计时。只有当事件触发后,在 n 秒内没有再次触发,函数才会执行。
应用场景:搜索框输入联想(等待用户停止输入后再发送请求)、窗口 resize 后调整布局等。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
// 防抖:防止抖动,多次触发只执行一次
// 用户输入完成后在进行关键词推荐,监听窗口(resize)变化
function debounce(fn, delay) {
let timer = null;
return (...args) => {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;// 清除定时器,防止内存泄露
}, delay);
};
}
// 测试
window.addEventListener("resize",debounce(() => {
console.log("防抖");
}, 1000)
);
</script>
</body>
</html>
节流
节流原理
规定一个时间间隔(比如 n 秒),在这个时间间隔内,函数只会执行一次。
如果在这段时间内多次触发事件,只有第一次(或最后一次)会生效。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
// 节流:节省流量,控制执行频率,规定时间内只执行一次
function throttle(fn, interval) {
let lastTime = 0;
return function (...args) {
const now = Date.now();
// 如果当前时间与上次执行时间的差大于间隔,则执行
if (now - lastTime >= interval) {
fn.apply(this, args);
lastTime = now;// 更新上次执行时间
}
};
}
// 测试
window.addEventListener(
"scroll",
throttle(() => {
console.log("节流");
}, 1000)
);
</script>
</body>
</html>
深拷贝
function deepCopy(obj) {
// 处理null 和 undefined
if (obj === null || typeof obj !== 'object') {
return obj;
}
// 处理日期
if (obj instanceof Date) {
return new Date(obj);
}
// 处理正则
if (obj instanceof RegExp) {
return new RegExp(obj.source, obj.flags);
}
// 处理数组和对象
let copy = Arry.isArray(obj) ? [] : {};
// 递归拷贝属性
Object.keys(obj).forEach(key => {
copy[key] = deepCopy(obj[key]);
})
return copy;
}