MST

星途 面试题库

面试题:JavaScript 自定义事件与性能优化及框架结合

在大型前端项目中,频繁触发自定义事件可能会影响性能。请阐述如何在使用 JavaScript 自定义事件时进行性能优化。同时,以 Vue.js 或 React 框架为例,说明如何在框架中更好地结合自定义事件来实现复杂业务逻辑,并分析框架自身的事件机制与原生 JavaScript 自定义事件之间的联系与区别。
41.7万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

1. JavaScript 自定义事件性能优化

  • 减少事件触发频率:使用防抖(Debounce)或节流(Throttle)技术。
    • 防抖:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。例如使用 lodashdebounce 方法:
import debounce from 'lodash/debounce';

const myFunction = () => {
    // 触发自定义事件的逻辑
};
const debouncedFunction = debounce(myFunction, 300);

// 在某个事件监听函数中调用
document.addEventListener('scroll', debouncedFunction);
- **节流**:规定一个单位时间,在这个单位时间内,只能触发一次事件。同样可以使用 `lodash` 的 `throttle` 方法:
import throttle from 'lodash/throttle';

const myFunction = () => {
    // 触发自定义事件的逻辑
};
const throttledFunction = throttle(myFunction, 300);

// 在某个事件监听函数中调用
document.addEventListener('scroll', throttledFunction);
  • 合理使用事件委托:将事件监听器添加到父元素上,利用事件冒泡机制,这样可以减少监听器的数量。例如:
<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') {
        // 触发自定义事件
        const customEvent = new CustomEvent('custom-li-click', { detail: event.target.textContent });
        event.target.dispatchEvent(customEvent);
    }
});
</script>
  • 优化事件处理函数:事件处理函数应尽量简单,避免复杂计算和 DOM 操作。如果有复杂计算,可将其放在异步任务队列中(如 setTimeoutrequestAnimationFrame)。

2. 在 Vue.js 中结合自定义事件实现复杂业务逻辑

  • 自定义事件定义与触发:在 Vue 组件中,可以通过 $emit 方法触发自定义事件。例如,有一个子组件 Child.vue
<template>
    <button @click="handleClick">Click me</button>
</template>

<script>
export default {
    methods: {
        handleClick() {
            this.$emit('custom-event', 'Some data');
        }
    }
};
</script>
  • 父组件监听自定义事件:在父组件 Parent.vue 中监听子组件触发的自定义事件:
<template>
    <Child @custom-event="handleCustomEvent"/>
</template>

<script>
import Child from './Child.vue';

export default {
    components: {
        Child
    },
    methods: {
        handleCustomEvent(data) {
            console.log('Received data from custom event:', data);
        }
    }
};
</script>
  • Vue 事件机制与原生 JavaScript 自定义事件联系与区别
    • 联系:本质上都是基于发布 - 订阅模式,用于组件间或元素间的通信。都可以传递数据。
    • 区别
      • 作用域:Vue 的自定义事件主要用于组件间通信,而原生 JavaScript 自定义事件作用于 DOM 元素。
      • 生命周期:Vue 自定义事件与 Vue 组件的生命周期紧密相关,例如在组件销毁时,相关事件监听器会自动解绑。而原生 JavaScript 需要手动解绑事件监听器。
      • 语法和便利性:Vue 使用 $emit@eventName 的语法,更简洁且与 Vue 的模板语法紧密结合。原生 JavaScript 需要通过 new CustomEventaddEventListener 等方法,相对复杂。

3. 在 React 中结合自定义事件实现复杂业务逻辑

  • 自定义事件定义与触发:在 React 中没有内置像 Vue 那样简单的自定义事件机制,但可以通过回调函数模拟。例如,有一个子组件 Child.js
import React from 'react';

const Child = ({ onCustomEvent }) => {
    const handleClick = () => {
        onCustomEvent('Some data');
    };

    return <button onClick={handleClick}>Click me</button>;
};

export default Child;
  • 父组件监听自定义事件:在父组件 Parent.js 中传递回调函数来监听自定义事件:
import React from'react';
import Child from './Child';

const Parent = () => {
    const handleCustomEvent = (data) => {
        console.log('Received data from custom event:', data);
    };

    return <Child onCustomEvent={handleCustomEvent}/>;
};

export default Parent;
  • React 事件机制与原生 JavaScript 自定义事件联系与区别
    • 联系:都基于事件驱动编程,都能处理用户交互或其他状态变化。
    • 区别
      • 事件合成:React 使用事件合成机制,将原生事件包装成合成事件对象,提供跨浏览器兼容性和更好的性能。而原生 JavaScript 自定义事件基于浏览器原生事件模型。
      • 绑定方式:React 通过 JSX 属性(如 onClick)绑定事件处理函数,原生 JavaScript 通过 addEventListener 绑定。
      • 作用域:React 事件处理函数的 this 指向问题需要特别注意,通常使用箭头函数或 bind 方法解决。原生 JavaScript 自定义事件处理函数 this 指向事件目标元素。