MST

星途 面试题库

面试题:JavaScript主表达式在事件驱动编程中的优化应用

在JavaScript事件驱动编程场景下,主表达式(如函数表达式常被用作事件处理程序)的使用频率很高。假设你正在开发一个复杂的Web应用,其中有大量的DOM元素绑定了事件处理程序,使用函数表达式作为事件处理程序可能会带来性能问题。请提出至少两种基于主表达式优化事件处理的策略,并从原理和具体实现方面进行详细阐述。
16.4万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

策略一:事件委托

  1. 原理:利用事件冒泡机制,将事件处理程序绑定到父元素上,而不是每个子元素都绑定。当子元素触发事件时,事件会向上冒泡到父元素,父元素通过判断事件源(event.target)来决定如何处理事件。这样可以减少事件处理程序的数量,从而提高性能。
  2. 具体实现
    <ul id="parent">
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
    </ul>
    <script>
        const parent = document.getElementById('parent');
        parent.addEventListener('click', function (event) {
            if (event.target.tagName === 'LI') {
                console.log('Clicked on:', event.target.textContent);
            }
        });
    </script>
    

策略二:使用命名函数而不是匿名函数表达式

  1. 原理:匿名函数表达式每次定义时都会创建一个新的函数实例,而命名函数在内存中只有一个实例。当大量使用匿名函数表达式作为事件处理程序时,会占用更多内存,影响性能。使用命名函数可以避免这种不必要的内存开销。
  2. 具体实现
    <button id="myButton">Click me</button>
    <script>
        function handleClick() {
            console.log('Button clicked');
        }
        const myButton = document.getElementById('myButton');
        myButton.addEventListener('click', handleClick);
    </script>
    

策略三:防抖与节流

  1. 原理
    • 防抖(Debounce):在事件触发后,等待一定时间(例如300毫秒),如果在这段时间内事件再次触发,则重新计时。只有当指定时间内没有再次触发事件时,才会执行事件处理程序。常用于搜索框输入等场景,避免频繁触发事件。
    • 节流(Throttle):规定在一定时间内,事件处理程序只能执行一次。比如设置每100毫秒执行一次,即使在这100毫秒内事件被触发多次,也只会执行一次事件处理程序。常用于滚动、缩放等频繁触发的事件场景。
  2. 具体实现
    • 防抖
      function debounce(func, delay) {
          let timer;
          return function() {
              const context = this;
              const args = arguments;
              clearTimeout(timer);
              timer = setTimeout(() => {
                  func.apply(context, args);
              }, delay);
          };
      }
      const input = document.getElementById('myInput');
      const debouncedFunction = debounce(function () {
          console.log('Input value:', this.value);
      }, 300);
      input.addEventListener('input', debouncedFunction);
      
    • 节流
      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;
              }
          };
      }
      window.addEventListener('scroll', throttle(function () {
          console.log('Scrolled');
      }, 100));