MST

星途 面试题库

面试题:JavaScript 函数构造函数性能优化之实际场景运用

假设你正在开发一个前端应用,其中需要频繁创建函数来处理用户输入的不同逻辑。从性能优化角度考虑,你会如何选择使用函数构造函数还是普通函数声明/表达式,并说明原因。同时,列举至少两种提升函数性能的具体措施。
11.3万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

函数构造函数与普通函数声明/表达式的选择及原因

  1. 普通函数声明/表达式优先
    • 原因:普通函数声明和表达式在解析代码时就被创建,具有更好的性能。它们在作用域链创建时就被定义,后续调用时直接从作用域中获取。而函数构造函数(如new Function('param1', 'param2', 'return param1 + param2'))是在运行时创建的,每次执行到该构造函数时都要创建一个新的函数对象,这会带来额外的性能开销。例如:
    // 普通函数声明
    function add1(a, b) {
        return a + b;
    }
    // 普通函数表达式
    const add2 = function (a, b) {
        return a + b;
    };
    // 函数构造函数
    const add3 = new Function('a', 'b','return a + b');
    
    多次调用add1add2比调用add3性能更好,因为add3每次调用都要重新创建函数对象。

提升函数性能的具体措施

  1. 减少函数内部的全局变量访问
    • 说明:访问全局变量比访问局部变量慢,因为作用域链查找全局变量需要遍历更长的链。例如:
    let globalVar = 10;
    function accessGlobal() {
        return globalVar;
    }
    function accessLocal() {
        let localVar = 10;
        return localVar;
    }
    
    accessLocal函数性能更好,因为它访问的是局部变量。可以将需要的全局变量缓存为局部变量来提升性能,如:
    let globalVar = 10;
    function accessGlobalOptimized() {
        let localVar = globalVar;
        return localVar;
    }
    
  2. 函数防抖和节流
    • 防抖(Debounce):在事件被触发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);
        };
    }
    
    • 节流(Throttle):规定一个单位时间,在这个单位时间内,只能触发一次函数。如滚动事件,频繁触发滚动回调函数会影响性能,使用节流可以在一定时间间隔内只执行一次。实现如下:
    function throttle(func, delay) {
        let lastTime = 0;
        return function () {
            const context = this;
            const args = arguments;
            const now = new Date().getTime();
            if (now - lastTime >= delay) {
                func.apply(context, args);
                lastTime = now;
            }
        };
    }