MST
星途 面试题库

面试题:JavaScript闭包性能优化与函数节流防抖

在使用闭包实现函数节流或防抖时,会涉及到闭包对性能的影响。请阐述如何在实现节流防抖功能的同时,尽可能优化闭包带来的性能开销。假设一个场景:页面上有一个滚动事件,需要在滚动时执行某个操作,利用闭包实现节流和防抖并优化其性能,写出关键代码并解释优化点。
26.6万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

节流(Throttle)

关键代码

function throttle(func, delay) {
    let timer = null;
    return function() {
        const context = this;
        const args = arguments;
        if (!timer) {
            func.apply(context, args);
            timer = setTimeout(() => {
                timer = null;
            }, delay);
        }
    };
}

// 使用节流
window.addEventListener('scroll', throttle(() => {
    // 执行某个操作
    console.log('Throttle: 滚动事件触发');
}, 300));

优化点解释

  1. 减少闭包引用:通过let timer = null;声明在外部作用域的变量timer来控制节流频率,在闭包内部复用这个变量,而不是每次都在闭包内重新声明。这样避免了闭包频繁创建新的变量引用导致的额外内存开销。
  2. 及时释放资源:当setTimeout执行完毕后,将timer重置为null,使得闭包内对timer的引用可以被垃圾回收机制回收,避免内存泄漏。

防抖(Debounce)

关键代码

function debounce(func, delay) {
    let timer = null;
    return function() {
        const context = this;
        const args = arguments;
        clearTimeout(timer);
        timer = setTimeout(() => {
            func.apply(context, args);
        }, delay);
    };
}

// 使用防抖
window.addEventListener('scroll', debounce(() => {
    // 执行某个操作
    console.log('Debounce: 滚动事件触发');
}, 300));

优化点解释

  1. 减少闭包引用:和节流类似,使用外部作用域的timer变量,避免在闭包内部频繁创建新的变量引用,降低内存开销。
  2. 及时清除定时器:每次触发事件时,通过clearTimeout(timer)清除之前设置的定时器,防止不必要的定时器执行,减少性能浪费。只有在最后一次触发事件经过delay时间后,才真正执行操作,从而达到防抖效果。同时,当定时器执行完毕,也会自动释放对timer的引用,利于垃圾回收。