loading...
JS八股面试题三
Published in:2023-08-14 | category: Typescript
Words: 2.8k | Reading time: 9min | reading:

JS八股面试题三

1.前端代码重构需要从哪些方面考虑?

前端代码重构是对现有代码进行优化和改进的过程,以提高代码质量、可维护性和性能。在进行前端代码重构时,需要从多个方面进行考虑和规划:
代码结构优化: 检查代码的组织结构,确保模块化、可扩展性和可维护性。拆分大型函数或组件,遵循设计模式和最佳实践。
命名和注释: 确保代码中的变量、函数、类和组件的命名具有描述性,易于理解。添加清晰的注释,解释代码的意图和功能。
重复代码消除: 寻找并消除重复的代码片段,可以将其提取为函数、组件或工具函数,以减少代码冗余。
性能优化: 评估代码的性能瓶颈,优化关键路径和性能敏感区域。减少不必要的 DOM 操作、网络请求和资源加载时间。
数据流管理: 使用状态管理库(如 Redux、Vuex、Mobx 等)来管理数据流,确保数据的一致性和可追踪性。
响应式设计: 确保应用在不同设备和屏幕尺寸上都能正常工作,采用响应式设计和媒体查询。
测试覆盖率提升: 增加代码的测试覆盖率,编写单元测试、集成测试和端到端测试,以确保代码的正确性和稳定性。
优化加载性能: 优化资源加载顺序,使用合适的打包工具和代码分割策略,以减少页面加载时间。
可访问性: 确保应用对于残障人士也具有良好的可访问性,遵循 Web Content Accessibility Guidelines(WCAG)。
代码规范: 遵循一致的代码规范和风格,可以使用代码风格检查工具(如 ESLint)来保持代码的一致性。
技术选型: 评估当前使用的技术栈是否仍然适合项目需求,是否需要更新或替换某些技术。
文档更新: 更新项目文档,记录代码改动、新增功能和更新的文档。
在进行前端代码重构时,还应该考虑项目的紧急程度、团队协作、风险管理等因素,以确保重构过程是有序、逐步的,并且不会影响现有的业务功能。

2.那重构的目的是什么?

前端代码重构的主要目的是改进现有代码的质量、可维护性、可读性和性能,以及减少技术债务。重构是一个有目的的过程,旨在使代码更加健壮、可扩展、易于理解和修改。以下是重构的一些主要目的:
代码质量提升: 通过重构,可以改进代码的结构、命名、注释和设计,从而提高代码的整体质量,减少代码的混乱和冗余。
可维护性增强: 重构可以使代码更易于维护,降低维护成本。通过拆分函数、模块化代码和应用设计模式,可以更容易地定位和修复 bug。
可读性改善: 重构可以使代码更易于理解,通过改善命名、提取函数、删除无用代码等方式,使代码更具可读性,新成员可以更快速地融入项目。
性能优化: 通过重构可以识别和改进性能问题,如减少不必要的计算、内存泄漏、资源加载等,提高应用的性能和响应速度。
减少技术债务: 随着时间的推移,项目中可能会积累技术债务,导致代码难以维护和扩展。重构可以帮助减少技术债务,保持代码的健康状态。
增加适应性: 重构可以使代码更易于适应变化,响应需求变更和新特性的引入,从而使项目更具灵活性。
降低风险: 通过提高代码质量和稳定性,重构可以降低出现严重错误和故障的风险,提高应用的稳定性。
提高团队协作: 规范的代码结构和命名可以促进团队成员之间的协作,减少代码冲突和误解。

3.为什么要减少HTTP请求?(这里应该是要回答请求的过程和性能之间的关系)

减少 HTTP 请求是前端性能优化的关键策略之一,这是因为 HTTP 请求的过程对于网页加载性能有着重要影响。以下是几个原因解释为什么要减少 HTTP 请求:
网络延迟和响应时间: 发起一个 HTTP 请求需要经过多个阶段,包括 DNS 解析、建立连接、发送请求、等待服务器响应、接收响应等,每个阶段都会增加网络延迟。减少请求意味着减少这些阶段的开销,从而降低页面加载时间,提供更好的用户体验。
带宽消耗: 每个 HTTP 请求都会消耗带宽,特别是在移动设备上。减少请求可以降低总体带宽消耗,有助于节省用户的数据流量。
浏览器并发限制: 大多数浏览器有并发请求限制,例如每个域名的同时请求数量有限。减少请求可以避免过多的请求被阻塞,提高并发性能。
页面渲染: 每个请求都会触发浏览器的渲染过程,包括样式计算、布局、绘制等。减少请求可以降低渲染开销,加速页面加载和交互响应。
移动设备性能: 移动设备的网络连接和处理能力相对较弱,较多的 HTTP 请求会对性能造成更大影响。减少请求可以改善移动设备上的用户体验。
为了减少 HTTP 请求,可以采取以下策略:
合并资源:将多个小资源合并为一个大资源,如合并 CSS、JS 文件。
使用雪碧图(Sprites):将多个小图标合并成一张图片,通过 CSS 中的背景定位来显示不同图标。
利用缓存:使用浏览器缓存机制,减少重复请求。
延迟加载:将不关键的资源(如图片、JavaScript)推迟加载,以提高页面的首次加载速度。
使用数据URI:将小图片直接嵌入到 CSS 中,避免额外的请求。
通过减少 HTTP 请求,可以显著提升网页加载性能,加快页面加载速度,提供更好的用户体验。

4. 怎么减少重排和重绘?

重排(Reflow)和重绘(Repaint)是浏览器渲染过程中的两个关键步骤,它们可能会对页面性能产生影响。重排是指计算并应用元素的几何属性(如位置、大小、布局等),而重绘是指更新元素的视觉外观(如颜色、背景等)。由于重排和重绘会触发浏览器重新计算和绘制页面,因此频繁的重排和重绘会降低页面性能。

以下是一些减少重排和重绘的方法:

使用 CSS Transitions 和 Animations: 使用 CSS Transitions 和 Animations 来实现动画效果,它们通常会在合适的情况下使用 GPU 加速,减少对页面布局的影响,从而减少重排。

使用 CSS Transform: 使用 CSS Transform 属性来实现平移、旋转、缩放等变换,这可以触发 GPU 加速,减少对布局的影响。

避免频繁操作样式: 避免在 JavaScript 中频繁操作样式,因为每次修改样式都可能触发重排和重绘。如果需要多次修改样式,可以使用 CSS 类名来一次性修改,减少对页面渲染的干扰。

使用 DocumentFragment: 当需要操作 DOM 元素集合时,可以使用 DocumentFragment 来避免多次重排和重绘,因为 DocumentFragment 可以在内存中进行操作,然后一次性插入到页面中。

将元素脱离文档流: 对于会导致重排的操作,可以将元素脱离文档流(例如使用 position: absolute 或 position: fixed),进行修改后再重新插入文档流中,以减少重排的影响。

批量更新: 对于需要多次修改 DOM 的情况,可以使用批量更新的方式,将多个修改操作合并为一个,然后一次性更新 DOM,从而减少重排和重绘。

避免频繁查询布局信息: 避免在循环中频繁查询布局信息(如元素的位置和尺寸),因为这可能会触发多次重排。可以使用缓存或一次性获取布局信息来优化。

5.如果不把DOM属性放在循环里面,具体应该怎么做?

在循环中频繁查询 DOM 属性可能会触发多次重排(Reflow),从而降低性能。为了避免这种情况,可以采取以下方法来优化代码:

缓存 DOM 属性: 在循环之前,将需要查询的 DOM 属性缓存到变量中。这样,在循环内部就不需要每次都去查询 DOM,而是直接使用已经缓存的属性。

const element = document.getElementById('myElement');const elementWidth = element.offsetWidth;const elementHeight = element.offsetHeight;for (let i = 0; i < array.length; i++) {  // 在循环内部使用 elementWidth 和 elementHeight,避免重复查询}

分离读写操作: 如果循环内部需要修改 DOM 属性,可以先在循环外部进行查询和计算,然后在循环内部执行修改操作。这样可以将读取和写入操作分离,减少重排的次数。

使用虚拟 DOM(Virtual DOM): 虚拟 DOM 是一种将 DOM 操作抽象为虚拟节点(Virtual Node)的技术,通过在虚拟 DOM 上进行操作,然后一次性将变更应用到实际 DOM,可以减少重排的次数。

6.defineProperty对于对象的哪些属性监听不到?

Object.defineProperty 方法用于在对象上定义新的属性或修改现有属性,并且可以设置属性的特性(例如,可写、可枚举、可配置等)。然而,Object.defineProperty 并不是适用于所有属性的监听。

Object.defineProperty 无法监听到以下情况的属性变化:

新增属性或删除属性: Object.defineProperty 无法监听对象属性的新增或删除操作,它只能监听已经存在的属性的变化。

数组的索引和长度: 对于数组对象,Object.defineProperty 不能监听数组的索引变化或长度变化,因为数组的索引和长度并不是普通的属性,而是特殊的内置属性。

内置对象的属性: 对于一些内置对象(如 Array、Date 等),Object.defineProperty 也无法监听属性的变化,因为这些对象的属性通常是内置的、无法通过普通方式重新定义的。

要在 JavaScript 中实现更全面的属性监听,你可以使用 Proxy 对象。Proxy 对象允许你拦截并自定义对象的操作,包括属性的访问、修改、添加和删除等。

Prev:
LeetCode刷题-20230906
Next:
JS八股面试题二