面试前端八股文十问十答第五期

面试前端八股文十问十答第五期

作者:程序员小白条个人博客

相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新!

⭐点赞⭐收藏⭐不迷路!⭐

1)介绍节流防抖原理、区别以及应用

**节流(Throttling)**是一种限制事件处理频率的技术。它确保在一定时间间隔内,事件处理函数只会被执行一次。如果在指定的时间间隔内多次触发事件,只有第一次触发会立即执行处理函数,随后的触发会被忽略,直到过了指定的时间间隔,才会再次执行处理函数。

**防抖(Debouncing)**是一种延迟执行的技术。它确保在事件触发后,只有在指定的时间间隔内没有再次触发时才会执行事件处理函数。如果在指定的时间间隔内又触发了相同的事件,则重新开始计时,等待下一次事件触发。

区别:

  • 时间点: 节流在一段时间内只执行一次,而防抖则在事件停止触发一段时间后执行。
  • 执行时机: 节流在一定时间内的连续触发事件中只执行第一次,而防抖在最后一次事件触发后的指定时间间隔内执行。
  • 适用场景: 节流适用于需要限制处理频率的场景,例如滚动事件、resize 事件等;防抖适用于需要等待一段时间后再执行处理函数的场景,例如输入框输入、按钮点击等。

应用:

  • 节流: 滚动加载、窗口 resize 事件、输入框输入事件等。
  • 防抖: 搜索框输入建议、按钮点击提交、窗口 resize 事件等。

2)简述MVVM

MVVM 是一种软件架构模式,用于构建用户界面。它将应用程序分为三个部分:模型(Model)、视图(View)和视图模型(ViewModel)。

  • 模型(Model):负责管理应用程序的数据和业务逻辑,提供数据接口供视图模型访问。
  • 视图(View):用户界面的呈现层,负责展示数据、接收用户输入,并将用户操作传递给视图模型。
  • 视图模型(ViewModel):连接视图和模型的中间层,负责处理视图的展示逻辑、响应用户输入,并调用模型层获取数据。它将模型数据转换为视图所需的数据格式,并通过数据绑定技术将视图和模型解耦。

MVVM 的优点:

  • 分离关注点(Separation of Concerns): MVVM 将应用程序分为模型、视图和视图模型三个部分,各自负责不同的职责,使得代码结构更加清晰,易于维护和扩展。
  • 可测试性(Testability): 由于视图模型将视图逻辑与界面分离,使得可以更方便地对视图模型进行单元测试,提高代码的可测试性。
  • 数据驱动(Data-Driven): MVVM 使用数据绑定技术实现视图和视图模型之间的数据同步,使得视图可以自动更新以反映模型数据的变化,提高了开发效率。

3)Vue底层实现原理

Vue.js 是一款流行的前端 JavaScript 框架,它的底层实现原理主要包括以下几个方面:

  • 响应式数据(Reactivity): Vue 使用响应式数据系统实现数据的双向绑定。它通过 Object.defineProperty() 方法对数据对象的属性进行劫持,当属性发生变化时,自动通知所有相关联的视图进行更新。
  • 虚拟 DOM(Virtual DOM): Vue 使用虚拟 DOM 技术实现高效的 DOM 更新。它通过在内存中维护一个虚拟 DOM 树,将视图的状态与真实 DOM 进行比较,找出差异,并仅更新需要更新的部分,以减少 DOM 操作次数,提高性能。
  • 模板编译(Template Compilation): Vue 将模板编译成渲染函数,以提高渲染性能。在编译阶段,Vue 将模板解析成抽象语法树(AST),然后将 AST 转换为渲染函数,最终生成可执行的 JavaScript 代码。
  • 组件化(Component-Based Architecture): Vue 提供了组件化的开发方式,允许将页面拆分成独立的组件,每个组件都有自己的状态和视图。Vue 使用虚拟 DOM 和响应式数据系统实现了组件的高效更新和通信。
  • 生命周期钩子(Lifecycle Hooks): Vue 提供了一系列的生命周期钩子函数,允许开发者在组件的不同阶段执行自定义逻辑。这些钩子函数包括 beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy 和 destroyed 等。

4)谈谈对vue生命周期的理解?

Vue 组件的生命周期包括创建、挂载、更新和销毁等阶段,每个阶段都有对应的生命周期钩子函数,可以在特定阶段执行相应的逻辑。

  • 创建阶段(Creation):
    • beforeCreate: 在实例初始化之后、数据观测 (data observer) 和 event/watcher 事件配置之前被调用。此时组件的实例还未初始化,无法访问数据和方法。
    • created: 在实例创建完成后被立即调用。此时实例已经完成了数据观测,但是尚未挂载到 DOM 上。可以在这个钩子函数中执行异步操作或初始化数据。
  • 挂载阶段(Mounting):
    • beforeMount: 在挂载开始之前被调用,相关的 render 函数首次被调用。在这之后,Vue 实例的 $elel 被关联,但尚未挂载到 DOM 上。
    • mounted: 在实例挂载到 DOM 后被调用。此时,Vue 实例已经挂载到 DOM 上,可以进行 DOM 操作或访问 DOM 元素。
  • 更新阶段(Updating):
    • beforeUpdate: 在数据更新之前被调用,发生在虚拟 DOM 重新渲染和打补丁之前。可以在这个钩子函数中进行状态更新之前的准备工作。
    • updated: 在数据更新完成后被调用。该钩子函数被调用时,DOM 已经更新,可以执行 DOM 相关的操作。但是,注意避免在这个钩子函数中触发无限循环的更新。
  • 销毁阶段(Destroying):
    • beforeDestroy: 在实例销毁之前被调用。此时,实例仍然完全可用,可以执行清理工作,如清除定时器、解绑事件等。
    • destroyed: 在实例销毁之后被调用。此时,实例的所有指令已经解绑,所有子实例也被销毁,可以执行一些最终的清理工作。

5)computed与watch

  • computed:
    • 特点: 计算属性是基于它们的依赖进行缓存的,只有在相关依赖发生改变时才会重新求值。计算属性的值会被缓存,只有当依赖发生改变时才会重新计算。
    • 适用场景: 当需要根据已有数据计算出新数据时,可以使用计算属性。例如,对数据进行过滤、排序、格式化等操作。
  • watch:
    • 特点: Watch 用于观察数据的变化并执行异步或开销较大的操作。可以监听数据的变化,并在数据变化时执行自定义的操作。
    • 适用场景: 当需要在数据变化时执行异步操作、操作 DOM、或执行其他非纯粹数据操作时,可以使用 Watch。例如,监听输入框内容的变化并发送网络请求。

6)组件中的data为什么是一个函数?

在 Vue 组件中,data 选项需要是一个函数,而不是一个对象。这是因为 Vue 组件是可复用的,当一个组件被多次使用时,如果 data 是一个对象,那么所有的组件实例都会共享同一个 data 对象,导致数据互相影响,从而产生意料之外的结果。

通过将 data 定义为一个函数,每次创建一个新的组件实例时,Vue 会调用该函数返回一个新的数据对象,从而保证每个组件实例都有独立的数据对象,互相之间不会产生影响。这样做可以确保组件之间的数据隔离,提高了组件的可复用性和可维护性。

因此,为了避免数据共享和互相影响的问题,Vue 要求将 data 定义为一个返回数据对象的函数,而不是直接定义为一个对象。

7)为什么v-for和v-if不建议用在一起

在 Vue 中同时使用 v-forv-if 可能会导致一些意料之外的结果,因为它们的优先级不同,可能会影响到渲染结果和性能。

  • 优先级不同: v-for 的优先级高于 v-if,意味着 v-for 在每次渲染时都会运行,而 v-if 的条件会在每次循环中重新评估。
  • 性能影响: 当数据量较大时,在每次循环中重新评估 v-if 条件可能会导致性能问题,因为即使在某些情况下不需要渲染某些项,循环也会执行,这可能会导致不必要的渲染和性能损耗。
  • 维护性差: 同时使用 v-forv-if 可能会导致模板变得难以理解和维护,因为在每次渲染时需要考虑循环和条件之间的交互关系。

虽然在某些情况下可能需要同时使用 v-forv-if,但通常建议尽量避免这种情况,可以通过重新组织数据、使用计算属性或在父组件中处理数据来减少 v-if 的使用,以提高代码的可读性和性能。

8)React/Vue 项目中 key 的作用

  • React 中的 key: 在 React 中,key 是用来标识列表中的每个元素的唯一性,帮助 React 识别哪些元素发生了变化、添加或删除。当列表中的元素发生变化时,React 会根据 key 来判断是更新现有元素还是创建新元素,从而提高列表渲染的效率。通常,key 应该是列表中每个元素的唯一标识符,可以是元素的 id 或其他唯一属性。
  • Vue 中的 key: 在 Vue 中,key 同样用于识别列表中的每个元素的唯一性,但其作用略有不同。key 主要用于 Vue 的虚拟 DOM 算法,在进行列表渲染时,Vue 会根据 key 来判断哪些元素是新创建的、被删除的或是已经存在的,从而尽可能地复用已存在的 DOM 元素,减少不必要的 DOM 操作,提高渲染性能。

9)vue组件的通信方式

Vue 组件之间的通信可以通过以下几种方式实现:

  • Props / Emit: 父子组件之间通过 Props(属性)传递数据,子组件通过 Emit(事件)向父组件发送消息。这是最基本的一种通信方式,适用于父子组件之间的简单通信。
  • 事件总线: 使用 Vue 的实例作为事件总线,通过 $emit$on 来进行组件间的通信。可以用于兄弟组件之间的通信或跨级组件之间的通信。
  • Vuex: Vuex 是 Vue 的状态管理库,用于集中式管理应用的所有组件的状态。通过在组件中派发 mutations 或 actions 来改变状态,从而实现组件间的通信和状态共享。
  • Provide / Inject: 父组件通过 provide 提供数据,子组件通过 inject 注入数据。适用于跨级组件之间的通信,但不推荐用于跨多层级的通信,以避免组件之间的耦合。
  • 事件总线: 使用第三方的事件总线库(如 EventBus)来实现组件间的通信。通过订阅和发布事件来实现组件之间的解耦。

10)nextTick的实现

nextTick 是 Vue 提供的一个异步方法,用于在 DOM 更新之后执行回调函数。它的实现原理是利用了浏览器的 microtask 和 macrotask 机制,确保回调函数在 DOM 更新之后执行。

具体来说,当调用 nextTick 方法时,Vue 会将传入的回调函数放入一个队列中,然后通过 microtask 或 macrotask 来执行这个队列中的回调函数。

  • 在现代浏览器中,Vue 使用 microtask(如 Promise)来异步执行回调函数,确保回调函数在 DOM 更新之后执行,但在当前 JavaScript 执行栈之后、下一个 UI 更新之前执行。
  • 在较老的浏览器中,如果不支持 microtask,则 Vue 会使用 macrotask(如 setTimeout)来异步执行回调函数,但会在下一个 UI 更新之后执行。

无论使用 microtask 还是 macrotask,nextTick 都能确保回调函数在 DOM 更新之后执行,从而避免了一些可能导致的 UI 更新问题。

开源项目地址:https://gitee.com/falle22222n-leaves/vue_-book-manage-system

前后端总计已经 900+ Star,1.5W+ 访问!

⭐点赞⭐收藏⭐不迷路!⭐

相关推荐
崔庆才丨静觅14 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606115 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了15 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅15 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅15 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅16 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment16 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅16 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊16 小时前
jwt介绍
前端