前端面试题详解整理10|.vite。nexttick的原理,触发 BFC 的条件,粘性定位的原理,判断变量是不是一个数组,如何浅拷贝数组,new Set()方法

71 阅读12分钟

小鹅通前端实习一面

1.自我介绍,如何接触的前端,公司在深圳,为什么会来深圳实习

2.什么是bfc BFC(Block Formatting Context)是 CSS 中的一个概念,用于描述块级盒子的布局规则。BFC 定义了块级盒子在页面上的布局及相互影响的规则,是页面布局的一个重要组成部分。

BFC 具有以下特性和作用:

  1. 垂直方向上的布局:BFC 中的元素在垂直方向上排列,相邻元素的上下边距不会重叠。

  2. 内部元素的封装:BFC 内部的所有元素会被包含在一个独立的空间内,不会影响到外部元素的布局。

  3. 浮动元素的包裹:BFC 可以包裹浮动元素,防止浮动元素对其他元素的影响。

  4. 清除浮动:BFC 可以包含浮动元素,并且会自动扩展以包含浮动元素。

  5. 外边距折叠:BFC 可以阻止外边距折叠,即相邻元素的上下外边距不会合并。

触发 BFC 的条件有多种,包括:

  • 根元素或包含根元素的元素。
  • 浮动元素(float 不为 none)。
  • 绝对定位元素(position 为 absolute 或 fixed)。
  • display 属性为 inline-block、table-cell、table-caption、flex、inline-flex、grid、inline-grid。
  • overflow 属性不为 visible 的块级盒子。

通过创建 BFC,可以解决一些常见的布局问题,如清除浮动、防止外边距折叠等,并且能够更加精确地控制页面布局。

3.粘性定位的原理是什么 粘性定位(sticky positioning)是 CSS 中一种介于相对定位(relative positioning)和固定定位(fixed positioning)之间的定位方式。它的特点是在滚动到元素的定位区域时,它会固定在容器的某个位置,直到容器的滚动到达指定的位置时,元素会恢复到原始的位置。

粘性定位的原理可以简单描述为:

  1. 元素相对于父容器进行定位,当元素在屏幕上滚动时,它会在指定的位置停止滚动,并保持在视口内可见。

  2. 当元素滚动超出父容器的边界时,它将恢复到普通的相对定位。

具体来说,粘性定位的原理如下:

  • 当元素距离父容器顶部的距离小于或等于容器顶部的偏移量时,元素将相对于容器顶部定位,跟随页面滚动。

  • 当元素距离父容器底部的距离小于或等于容器底部的偏移量时,元素将相对于容器底部定位,保持在容器内的固定位置。

  • 当元素在父容器内滚动时,其位置将根据父容器的滚动位置动态调整,直到达到指定的偏移量。

粘性定位通常用于创建滚动时固定的导航栏、侧边栏或页脚等元素,以提高页面的用户体验和导航性。

4.如何判断变量是不是一个数组 在 JavaScript 中,可以使用 Array.isArray() 方法来判断一个变量是否为数组。该方法接收一个参数,并返回一个布尔值,指示参数是否为数组。

示例代码如下所示:

let arr = [1, 2, 3];

if (Array.isArray(arr)) {
  console.log('arr 是一个数组');
} else {
  console.log('arr 不是一个数组');
}

如果 arr 是一个数组,则上述代码会输出 'arr 是一个数组';否则,输出 'arr 不是一个数组'

这种方法适用于所有 JavaScript 环境,包括浏览器和 Node.js。

5.如何浅拷贝数组 浅拷贝数组意味着创建一个新数组,并将原始数组中的元素复制到新数组中。在 JavaScript 中,可以使用几种方法来实现浅拷贝数组,包括使用 slice() 方法、concat() 方法、spread 操作符(...)和 Array.from() 方法等。

  1. 使用 slice() 方法

    let originalArray = [1, 2, 3];
    let shallowCopy = originalArray.slice();
    
  2. 使用 concat() 方法

    let originalArray = [1, 2, 3];
    let shallowCopy = originalArray.concat();
    
  3. 使用 spread 操作符(...)

    let originalArray = [1, 2, 3];
    let shallowCopy = [...originalArray];
    
  4. 使用 Array.from() 方法

    let originalArray = [1, 2, 3];
    let shallowCopy = Array.from(originalArray);
    

以上方法都会创建原始数组的一个浅拷贝,即新数组中的元素与原始数组中的元素具有相同的值,但是引用地址不同。这意味着对新数组中的元素进行修改不会影响到原始数组,但如果原始数组中的元素是对象或数组等引用类型,则仍然是浅拷贝,修改新数组中的对象或数组的属性会影响到原始数组。

6.new Set()方法的作用是什么,new Set([{a:'1'},{a:'1'}])的返回值是什么 Set 是 JavaScript 中的一种数据结构,用于存储唯一值(无重复)。new Set() 方法用于创建一个空的 Set 对象,或者根据给定的可迭代对象创建一个 Set 对象。在给定的可迭代对象中,重复的元素将被忽略,只保留一个。

例如,new Set([1, 2, 3, 2, 1]) 将返回一个包含唯一值 [1, 2, 3] 的 Set 对象。

对于 new Set([{a:'1'},{a:'1'}]),由于每个对象都是独立的引用,因此两个对象被视为不同的元素,即使它们的属性值相同。因此,Set 对象会将两个对象都保留下来,并且不会将它们视为重复的元素。因此,返回值将是一个包含两个对象的 Set 对象。

7.nexttick的原理

process.nextTick() 是 Node.js 中的一个特殊函数,用于将回调函数放入事件循环的下一个阶段。它的原理涉及到 Node.js 的事件循环机制。

Node.js 中的事件循环是基于 libuv 库实现的,它采用了类似于浏览器中的事件循环的机制。事件循环主要由以下几个阶段组成:

  1. Timers 阶段:处理定时器操作,例如 setTimeout()setInterval()

  2. I/O Callbacks 阶段:处理异步 I/O 操作的回调函数,例如网络请求、文件读写等。

  3. Idle, Prepare 阶段:内部使用,可以忽略。

  4. Poll 阶段:轮询新的 I/O 事件,执行相关的回调函数。

  5. Check 阶段:处理 setImmediate() 设定的回调函数。

  6. Close Callbacks 阶段:处理一些关闭的回调函数,例如 socket.on('close', ...)

process.nextTick() 方法会将回调函数放入事件循环的 Check 阶段,以确保回调函数在当前操作结束后立即执行,而不必等待下一个事件循环迭代。这意味着,process.nextTick() 的回调函数会在当前事件循环迭代的末尾被调用,优先于其他阶段(包括微任务和宏任务)。

由于 process.nextTick() 的回调函数会在当前事件循环迭代的末尾被调用,因此它的执行优先级高于 Promise 的 then()catch() 方法、setImmediate()setTimeout()。这使得它在某些情况下比这些方法更加适用,例如在异步函数执行完成后立即执行回调函数。

8.微任务和宏任务 微任务(Microtask)和宏任务(Macrotask)是 JavaScript 中用于处理异步任务的两种不同的任务队列。它们的执行顺序和优先级不同,对于理解 JavaScript 中的事件循环(Event Loop)至关重要。

宏任务(Macrotask):

  • 宏任务是由浏览器引擎提供的任务,通常包括:

    • setTimeout 和 setInterval 回调函数。
    • DOM 事件处理程序。
    • I/O 操作(如文件读写、网络请求等)的回调函数。
  • 宏任务队列是一个 FIFO(先进先出)队列,每次只能执行一个任务,当宏任务队列中的任务执行完毕后,浏览器会重新渲染页面,并检查是否需要触发重新布局(reflow)和重绘(repaint)。

微任务(Microtask):

  • 微任务是由 JavaScript 引擎提供的任务,通常包括:

    • Promise 的处理函数(then、catch、finally)。
    • async/await 中的 await 表达式。
  • 微任务队列也是一个 FIFO 队列,但它具有比宏任务更高的优先级。当微任务队列不为空时,JavaScript 引擎会优先执行微任务队列中的任务,直到微任务队列为空为止。这意味着微任务可以在浏览器渲染之前执行,因此对于执行异步操作后需要立即更新 UI 的情况特别有用。

事件循环(Event Loop):

  • 事件循环是 JavaScript 引擎用于处理异步任务的机制,它不断地从宏任务队列中取出任务执行,直到宏任务队列为空为止。在执行宏任务的过程中,如果遇到微任务,JavaScript 引擎会优先执行微任务队列中的任务,直到微任务队列为空。

  • 这种宏任务与微任务交替执行的机制称为事件循环(Event Loop),它确保了 JavaScript 代码的执行顺序符合预期,并且能够有效地处理异步任务。

综上所述,微任务和宏任务是 JavaScript 中用于处理异步任务的两种不同的任务队列,它们在执行顺序和优先级上有所不同,但共同参与了 JavaScript 引擎的事件循环机制。

9.讲讲vite打包工具的构建流程 Vite 是一种现代化的构建工具,旨在提供快速的开发体验。它与传统的打包工具(如Webpack和Parcel)不同,采用了基于浏览器原生 ES 模块的开发模式,利用浏览器的本地 ES 模块支持来提供实时的模块热更新,从而加快了开发和构建的速度。

以下是 Vite 的构建流程概述:

  1. 启动开发服务器

    • 在开发模式下,Vite 会启动一个基于浏览器原生 ES 模块的开发服务器。当浏览器请求某个模块时,服务器会根据请求动态地构建模块并返回给浏览器。
  2. ES 模块解析

    • 当浏览器请求一个模块时,Vite 首先解析该模块的代码,包括处理 import 语句和解析模块路径。
  3. 构建模块依赖

    • Vite 会分析模块的依赖关系,包括静态依赖(通过 import 语句引入的模块)和动态依赖(通过动态 import 语句引入的模块)。
  4. 转换和编译

    • 对于非 JavaScript 类型的模块(如 TypeScript、Vue 单文件组件等),Vite 会将其转换为 JavaScript 代码,以便浏览器能够理解和执行。
  5. 模块热更新

    • 在开发模式下,Vite 会利用浏览器的本地 ES 模块支持来实现实时的模块热更新。当代码发生变化时,Vite 会重新构建受影响的模块,并通过 WebSocket 协议通知浏览器更新页面内容,从而实现快速的开发和调试。
  6. 生产模式构建

    • 在生产模式下,Vite 会对项目进行优化和打包,包括代码压缩、资源合并、代码分割等,以提高页面加载性能和用户体验。

总的来说,Vite 的构建流程具有轻量、快速的特点,利用现代化的开发模式和浏览器原生支持的特性,提供了更加快速、实时的开发体验,适合于现代化的 Web 开发项目。

10.如果遇到用户反馈页面的性能比较差,我们需要做一个分析然后做迭代优化,你该怎么做这个事情 优化页面性能是一个复杂而系统的过程,需要结合多个方面进行分析和优化。以下是一些通用的步骤和方法,可以帮助你进行页面性能优化:

  1. 分析页面加载性能

    • 使用浏览器的开发者工具(如 Chrome DevTools)进行页面加载性能分析,查看页面加载时间、资源加载情况、渲染时间等指标。
    • 使用性能分析工具(如 Lighthouse)对页面进行全面的性能评估,包括页面加载速度、用户交互响应时间、可访问性等方面的指标。
  2. 优化网络请求

    • 减少 HTTP 请求的数量,合并和压缩资源文件(如 CSS、JavaScript)。
    • 使用 CDN 加速静态资源的加载,提高资源的下载速度。
    • 使用资源预加载和懒加载技术,优化资源的加载顺序和时机。
  3. 优化前端代码

    • 减少 JavaScript 和 CSS 文件的大小,删除不必要的代码和注释,压缩和混淆代码。
    • 使用异步加载和延迟加载技术,提高页面的渲染速度。
    • 避免使用过多的 DOM 元素和复杂的 CSS 选择器,优化页面的渲染性能。
  4. 优化页面渲染

    • 使用 CSS 动画代替 JavaScript 动画,减少页面的重绘和回流。
    • 使用图片懒加载技术,延迟加载图片资源,减少页面加载时间。
    • 使用缓存和浏览器本地存储技术,提高页面的访问速度和用户体验。
  5. 优化移动端性能

    • 使用响应式设计或移动优先设计,确保页面在不同设备上的显示效果和性能。
    • 使用移动端特有的优化技术,如响应式图片、Viewport 设置、手势事件优化等。
  6. 持续监控和迭代优化

    • 定期监控页面性能指标,收集用户反馈和体验数据,发现和解决性能问题。
    • 根据监控数据和用户反馈,持续进行迭代优化,改进页面的性能和用户体验。

通过以上步骤和方法,你可以全面地分析和优化页面性能,提高页面的加载速度、渲染性能和用户体验,从而提升网站的整体质量和竞争力。

反问

作者://鲨鱼辣椒
链接:www.nowcoder.com/discuss/595…
来源:牛客网