MST

星途 面试题库

面试题:JavaScript 函数作为值传递时,如何优化高阶函数调用的性能?

高阶函数在 JavaScript 开发中经常用到,函数作为值传递给高阶函数时,可能会出现性能问题。请详细说明优化高阶函数调用性能的方法,例如如何减少不必要的函数创建、如何避免重复计算等,并结合实际代码示例进行讲解。
13.2万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

减少不必要的函数创建

  1. 复用已有的函数:避免每次调用高阶函数时都创建新的函数。例如,在Array.prototype.map方法中,不要每次都使用箭头函数创建新函数,而是复用已定义的函数。
// 定义一个复用的函数
function double(num) {
    return num * 2;
}
const numbers = [1, 2, 3];
// 复用函数
const result = numbers.map(double);
console.log(result); 
  1. 使用防抖(Debounce)和节流(Throttle):对于频繁调用的高阶函数,如window.addEventListener('scroll', () => { /* 处理逻辑 */ }),如果处理逻辑复杂,会导致性能问题。
    • 防抖:在事件被触发 n 秒后再执行回调,如果在这 n 秒内又触发了事件,则重新计时。例如,搜索框输入时,频繁触发搜索请求会浪费资源,使用防抖可以优化。
function debounce(func, delay) {
    let timer;
    return function() {
        const context = this;
        const args = arguments;
        clearTimeout(timer);
        timer = setTimeout(() => {
            func.apply(context, args);
        }, delay);
    };
}
// 模拟搜索请求
function search() {
    console.log('Searching...');
}
const debouncedSearch = debounce(search, 500);
document.getElementById('searchInput').addEventListener('input', debouncedSearch);
- **节流**:规定在一个单位时间内,只能触发一次函数。例如,滚动条滚动时,每 200ms 触发一次处理函数。
function throttle(func, delay) {
    let lastTime = 0;
    return function() {
        const now = new Date().getTime();
        const context = this;
        const args = arguments;
        if (now - lastTime >= delay) {
            func.apply(context, args);
            lastTime = now;
        }
    };
}
// 模拟滚动处理
function handleScroll() {
    console.log('Scrolling...');
}
const throttledScroll = throttle(handleScroll, 200);
window.addEventListener('scroll', throttledScroll);

避免重复计算

  1. 记忆化(Memoization):对于相同输入会产生相同输出的函数,将结果缓存起来,下次遇到相同输入直接返回缓存结果。例如,计算斐波那契数列时,递归方法会有大量重复计算。
function memoize(func) {
    const cache = {};
    return function(...args) {
        const key = args.toString();
        if (cache[key]) {
            return cache[key];
        }
        const result = func.apply(this, args);
        cache[key] = result;
        return result;
    };
}
function fibonacci(n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}
const memoizedFibonacci = memoize(fibonacci);
console.log(memoizedFibonacci(10)); 
  1. 提前计算常量:在高阶函数内部,如果有一些值不随函数调用变化,可以提前计算好,避免每次调用都计算。
// 假设要对数组元素进行复杂计算,其中部分计算是常量
const constantValue = Math.PI * 2;
function complexCalculation(num) {
    return num * constantValue + Math.sqrt(num);
}
const numbersArray = [1, 2, 3];
const results = numbersArray.map(complexCalculation);
console.log(results);