最新2024前端面试八股文

3,913 阅读17分钟

整理的前端面试八股文

css盒子模型

在 CSS 中,盒子模型分为标准盒子模型和 IE 盒子模型。

标准盒子模型:总宽度 = 内容宽度(width) + 内边距(padding) + 边框(border) + 外边距(margin)。

IE 盒子模型:总宽度 = 内容宽度(width) + 外边距(margin),其中内容宽度包含了内边距(padding)和边框(border)。

通过 box-sizing 属性可以切换这两种模型,box-sizing: content-box 为标准模型,box-sizing: border-box 为 IE 模型。

盒子坍塌

在 CSS 中,盒子坍塌(也称为外边距合并)是指当两个或多个垂直相邻的块级元素的外边距相遇时,它们会合并成一个外边距。

例如,如果一个元素的下边距为 20px ,紧挨着它的下一个元素的上边距为 30px ,最终两个元素之间的外边距不是 50px ,而是 30px (取两者中的较大值)。

解决盒子坍塌的常见方法有:为父元素添加 overflow: hidden; 、使用 padding 代替 margin 、使用 flex 或 grid 布局等。

什么是原型和原型链

每个对象都有一个原型属性,在浏览器中显示为__proto__,它指向了构造函数的prototype属性,它是一个原型对象

这样同类对象就共用了同一个原型对象,实现了对象间的属性共享

在访问对象属性时,如果实例本身没有该属性,则会从原型上查找,如果原型上仍没有该属性,则从原型对象的原型上继续向上查找,直到为最终为null停止查找。这样的实例与原型之间的层级关系称为原型链

实现继承的几种方法

原型链继承

将父实例赋值给子类的prototype,这样子实例的原型指向了父实例,继承了父实例的属性

缺点:父实例的私有实例属性被继承为了原型属性

构造函数继承

在子类的构造函数中调用父类的构造函数,并把子类的this传给父类,可以继承父类实例属性

缺点:无法继承原型属性,所以这种方式使用较少

组合继承

结合了原型链继承和构造函数的继承。

缺点:调用了两次构造函数

寄生组合继承

在组合继承的基础上,不新建父类实例,而通过Object.create将原型指向父类的prototype

多重继承

通过寄生组合继承多个父类

new 过程发生了什么

代码示例

创建一个对象,该对象的原型指向构造函数的prototype属性

将该对象赋值给构造函数中的this,并执行构造函数

如果构造函数返回一个对象,则返回该对象,没有则返回创建的对象

什么是闭包

闭包就是能读取其他函数内部变量的函数

内部函数存在对外部函数作用域变量的引用就会形成闭包

闭包可以实现对函数内部属性和方法的私有化

经典场景:函数返回一个函数,在外部仍可以访问内部变量,防抖节流

js事件循环机制

js是单线程,所有代码放到执行栈中执行

当遇到异步函数时,将异步回调放入一个任务队列中

执行完执行栈中的同步任务,会去任务队列里按顺序执行寄存的函数

如此往复,称为事件循环

异步任务又分为

宏任务(macro-task):setTimeout、setInterval...

微任务(micro-task):Promise...

同步任务->微任务->宏任务

this指向

普通函数指向函数的调用者,箭头函数指向函数所在的作用域,注意理解作用域,只有函数的{}构成作用域,对象的{}以及 if(){}都不构成作用域;

call、bind、apply的作用区别

三者都能改变函数this指向

apply、call调用函数,传参形式不同,apply接受一个数组参数,call接受多个参数,以队列形式传入

bind不调用函数,它返回新函数,传入的参数将作为新函数的值传入

Promise和 手写promise

Promise是处理异步任务的一种方式

一个Promise必然处于pending(待定)、fulfilled(已成功)、rejected(已失败)三种状态

通过resolve和reject切换promise状态,通过then方法通知promise执行结果

通过定时器和任务队列的方式实现异步任务

async/await

async/await可以让异步操作像同步一样执行,可以让多个异步任务以队列的方式依次执行

await后面接Promise对象

await只能在async函数中使用,不然会报错

async函数返回的是一个Promise对象

async/await通过generator函数实现

介绍下最近常用的ES6语法

es6泛指es5.1以后的js下一代标准语法,自2015年每年推出一个版本,包括ES2015-ES2020等

解构赋值、箭头函数、模板字符串、展开运算符(扩展对象,只能做到当对象属性是 基本数据类型 才是 深拷贝,如果是 引用数据类型,那就是浅拷贝)。。。

setTimeout执行机制

防抖和节流

防抖和节流是常见的 JavaScript 优化技术。

防抖:在事件被频繁触发时,只有在指定的时间间隔内没有再次触发事件,才会执行相应的回调函数。例如,用户输入搜索时,只有在停止输入一段时间后才发起搜索请求。

节流:在指定时间间隔内,无论事件触发多少次,只执行一次回调函数。比如滚动事件,每隔一定时间执行一次处理逻辑,而不是每次滚动都执行。

webpack原理、构建的过程

「吐血整理」再来一打Webpack面试题

webpack是一个整合打包的工具

功能:模块打包,将不同模块的代码整合一起,并保证引用正确。解析特殊语法,es6、vue、less、jsx等,转译成浏览器能识别的语言。功能扩展,通过插件等方式拓展功能,例如按需加载、代码压缩等,提高自动化和工程化程度

构建过程: 读取配置、确认入口文件、编译模块、完成输出

webpack plugin和loader区别

在 Webpack 中,Plugin(插件)和 Loader(加载器)是两个不同的概念。

Loader 主要用于转换模块的源代码。比如说,把 CSS 文件转换为 JavaScript 可以理解的模块,或者把Script 代码转换为 JavaScript 代码。就好比是一个“翻译官”,把一种特定格式的内容翻译成 Webpack 能处理的形式。

Plugin 则具有更广泛的功能,它能参与到 Webpack 构建的整个生命周期中。比如可以在打包开始、结束时执行一些操作,或者处理模块之间的依赖关系等。Plugin 就像是一个“全能助手”,能在各个关键节点发挥作用,实现更复杂的功能。

总的来说,Loader 专注于模块内容的转换,Plugin 则能在整个构建流程中提供更全面的控制和扩展。

是否有 手写webpack插件

sourcemap是什么

SourceMap 是一种在源代码和生成的代码(例如经过压缩、转换后的代码)之间建立映射关系的文件。

打个比方,如果您的原始 JavaScript 代码经过处理(比如压缩、混淆)后变得难以理解和调试,SourceMap 就像是一张地图,它能告诉开发者,处理后的代码中的每一行是由原始代码中的哪一行转换而来的。

这样,当在浏览器中调试代码时,如果出现错误,开发者可以通过 SourceMap 快速定位到原始代码中的准确位置,从而更方便地找出问题所在,进行修复和优化。

前端热更新HMR原理

前端热更新 HMR(Hot Module Replacement)原理是指在网页开发过程中,能够在应用运行时,无需完全刷新页面就能实时更新模块的代码。

在实现上,当代码发生变化时,Webpack 等构建工具会监测到变化,并重新编译相关模块。然后,通过特定的机制将新模块的代码传输到浏览器。浏览器接收到新模块代码后,会对比新旧模块的差异,只更新发生变化的部分,而不是重新加载整个页面。这样可以极大地提升开发效率和用户体验

前端精度问题产生的原因和解决办法

前端精度问题产生的原因主要有以下几点:

  1. 浮点数的二进制表示存在精度限制。
  2. 计算机在进行数值运算时的舍入误差。

解决办法包括:

  1. 对于精度要求高的计算,使用专门数值库,如 bigDecimal.js 。
  2. 进行数值比较时,设置一个合理的误差范围。
  3. 在涉及到金额等重要数据时,以分为单位存储和计算,避免使用浮点数。

两个超大数字相加,不能使用bigint

性能优化概述

  1. 减少 HTTP 请求:合并文件、使用雪碧图等。
  2. 压缩资源:如压缩 CSS、JS、图片等。
  3. 优化图片:选择合适的图片格式,进行适当的压缩。
  4. 缓存策略:利用浏览器缓存,设置合适的缓存头。
  5. 代码优化:避免不必要的计算和重复操作。
  6. 加载:延迟加载非关键资源。
  7. 减少 DOM 操作:避免频繁的 DOM 重绘和重排。

浏览器渲染的过程

首先,浏览器获取 HTML 。然后对文档进行解析,构建 DOM 树(文档对象模型树),这个树结构表示了页面的结构。

接着,浏览器获取 CSS 样式表,并对其进行解析,生成 CSSOM 树(CSS 对象模型树)。

之后,将 DOM 树和 CSSOM 树合并成渲染树。渲染树只包含需要显示的节点和对应的样式信息。

再然后,进行布局计算,确定每个节点在屏幕上的位置和大小。

最后,进行绘制操作,将页面内容呈现到屏幕上。

这个过程是一个复杂但有序的流程,各个步骤相互配合,以确保网页能够正确且高效地展示给用户。

JS垃圾回收

Cookie、session、sessionStorage、localStorage的区别

Cookie 是存储在用户浏览器一小段文本数据,会随每次请求发送到服务器,大小有限制,一般 4KB 。

Session 是服务器端存储的用户会话数据,通过在 Cookie 中存储一个唯一的 Session ID 来关联服务器端的 Session 数据。

SessionStorage 是浏览器提供的本地存储机制,数据仅在当前会话(即当前页面标签)有效,关闭页面后数据会被清除。

LocalStorage 也是浏览器提供的本地存储机制,但数据长期有效,除非手动清除或达到存储容量上限。

伪元素的作用

http1.0 http2.0

HTTP 1.0 和 HTTP 2.0 主要有区别:

数据传输格式

  • HTTP 1.0 是文本格式传输数据。
  • HTTP 2.0 采用二进制格式传输数据。

多路复用

  • HTTP 1.0 不支持多路复用,请求按顺序依次发送和响应。
  • HTTP 2.0 支持多路复用,多个请求可在同一连接上并发处理。

头部压缩

  • HTTP 1.0 头部信息重复且未压缩。
  • HTTP 2.0 对头部进行压缩,减少传输数据量。

服务器推送

  • HTTP 1.0 不支持服务器推送。
  • HTTP 2.0 支持服务器主动向客户端推送资源。

http和https

HTTP 和 HTTPS 的主要区别如下:

安全性

  • HTTP 是明文传输,数据在网络中传输容易被窃取和篡改
  • HTTPS 采用 SSL/TLS 加密,数据传输更安全。

端口

  • HTTP 通常使用 80 端口。
  • HTTPS 通常使用 443 端口。

证书

  • HTTPS 需要从权威证书颁发机构购买证书,以证明服务器的身份。

连接建立

  • HTTP 连接建立相对简单。
  • HTTPS 连接建立时需要进行 SSL/TLS 握手,过程更复杂,会有一定的性能开销。

http缓存

HTTP 缓存机制主要有以下几种:

  1. 强缓存:通过 Expires 和 Cache-Control 头部字段控制。Expires 给出具体的过期时间,Cache-Control 可设置 max-age 等参数。
  2. 协商缓存:通过 Last-Modified 和 If-Modified-Since 或者 ETag 和 If-None-Match 头部字段实现。服务器返回资源的标识,客户端再次请求时携带标识,服务器根据标识判断资源是否有更新。

react diff算法

React 的 Diff 算法是用于比较新旧虚拟 DOM 树以确定最小化更新操作的机制。

主要原则包括:

  1. 同级比较:只对同一层级的节点进行比较。
  2. 类型判断:不同类型的节点直接替换。
  3. 基于 key 值优化:通过给节点设置 key 值,提高比较的准确性和效率。

其目的是在更新组件时,尽可能减少对真实 DOM 的操作,从而提高性能。

react useEffect、useMemo、useCallback的作用和区别

useEffect 主要用于处理副作用,比如数据获取、订阅事件、手动修改 DOM 等操作。它接收一个函数作为回调,在组件渲染后执行,可以根据第二个参数控制执行时机。

useMemo 用于缓存计算结果,当依赖项不变时,返回之前计算的结果,避免不必要的重复计算,从而优化性能。

useCallback 用于缓存函数,当依赖项不变时,返回之前缓存的函数,主要用于优化子组件的重新渲染。

它们的区别在于:

  • useEffect 侧重于处理副作用操作。
  • useMemo 侧重于缓存计算值。
  • useCallback 侧重于缓存函数。

react useState的用法和原理

useState 是 React Hooks 中的一个函数,用于在函数组件中添加状态。

用法:

import React, { useState } from'react';

function MyComponent() {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

原理:useState 会在组件首次渲染时初始化状态值。当调用 setCount 等更新函数时,会触发组件的重新渲染,并更新对应的状态值。

react setState是异步还是同步

在 React 中,setState 在大多数情况下是异步的,但在某些特殊情况下可能表现为同步。

在 React 的合成事件和生命周期函数中,setState 通常是异步的,这是为了提高性能和批处理更新,避免频繁地重新渲染组件。

然而,在setState的回调函数中,以及在原生的 DOM 事件处理函数中,setState是同步的。

为什么setState是异步的

在 React 中,setState 通常是异步的,主要是为了提高性能和实现批处理更新。这样可以避免频繁地同步更新状态导致不必要的多次重新渲染,而是将多个 `setState 调用合并在一起进行一次更新,从而优化性能。

什么是hooks闭包陷阱

在 React 的 Hooks 中,“闭包陷阱”指的是由于函数组件中的闭包特性,可能导致一些不符合预期的情况。比如,当使用 useState 钩子定义状态,并在一个回调函数或异步操作中引用这个状态时,由于闭包的存在,获取到的可能是旧的状态值,而不是最新的状态值。这可能会导致逻辑错误,影响组件的正确行为。

react性能优化

React 性能优化可以从以下几个方面进行:

  1. 合理使用 shouldComponentUpdatePureComponent 来避免不必要的重新渲染。
  2. 减少不必要的状态更新,避免在每次状态改变时都进行重新渲染。
  3. 对列表进行优化,例如使用 key 属性来提高渲染效率。
  4. 避免在渲染过程中进行复杂的计算,将其移到 useMemouseCallback 中。
  5. 懒加载组件和数据,减少初始加载的负担。

react key的作用

在 React 中,key 是用于帮助 React 识别哪些元素发生了改变,从而更高效地更新虚拟 DOM。给列表中的元素添加 key 属性,可以让 React 更准确地判断是新增、删除还是更新元素,避免不必要的重新渲染,提高渲染性能。

react 类组件和函数组件的区别 (多次问到)

React 类组件和函数组件主要有以下区别:

语法

  • 类组件通过 class 定义,需要继承 React.Component 并实现 render 方法。
  • 函数组件是一个普通的 JavaScript 函数,直接返回要渲染的内容。

状态管理

  • 类组件使用 this.state 来管理内部状态,通过 this.setState 更新状态。
  • 函数组件使用 useState 钩子来管理状态。

生命周期

  • 类组件有完整的生命周期方法,如 componentDidMount 等。
  • 函数组件没有传统的生命周期方法,而是通过 useEffect 钩子模拟类似的行为。

逻辑复用

  • 类组件通过继承和高阶组件实现逻辑复用。
  • 函数组件通过自定义钩子实现逻辑复用。

react 什么是高阶组件

在 React 中,高阶组件是一个函数,它接受一个组件作为参数,并返回一个新的组件。这个新组件通常会对传入的组件进行功能增强、属性修改、逻辑封装等操作。

例如,可以通过高阶组件为组件添加一些通用的逻辑,如权限控制、数据获取等。

react 有没有像vue-router中的路由守卫

在 React 中,没有像 Vue Router 中那样明确的路由守卫概念。但可以通过一些方式来实现类似的功能,比如在路由组件的生命周期方法中进行条件判断和处理,或者使用一些第三方的路由库提供的类似功能。

react fiber

React Fiber 是对 React 核心算法的一种重新实现。它的主要目的是通过将渲染过程拆分成小任务,实现更灵活的优先级调度和更好的用户交互响应。

在传统的 React 渲染中,更新操作是同步且不可中断的,这可能导致在复杂的组件树更新时出现卡顿。

而 React Fiber 引入了一种新的协调机制,能够在必要时暂停、恢复和重新安排渲染工作,从而提高应用的性能和用户体验。

ts type和interface区别

  1. 扩展方式不同:

    • interface 可以通过继承来扩展。
    • type 不能通过继承扩展,但可以通过交叉类型(&)来组合。
  2. 定义方式不同:

    • interface 用于定义对象类型。
    • type 不仅可以定义对象类型,还可以定义联合类型、交叉类型、元组等。
  3. 同名合并:

    • 多次声明同名的 interface 会自动合并其成员。
    • type 不会自动合并。

ts 泛型

在 TypeScript 中,泛型是一种在定义函数、类或接口时,不预先指定具体的数据类型,而是在使用时再指定的技术。它增强了代码的复用性和灵活性。

react 组件是什么ts类型

react useEffect和ues

vue 响应式原理

vue与react的区别

Vue 和 React 有以下一些区别:

  1. 数据绑定方式:

    • Vue 采用双向数据绑定,通过 v-model 等指令实现。
    • React 通常是单向数据流,数据从父组件流向子组件。
  2. 模板语法:

    • Vue 有自己特定的模板语法,更接近 HTML 。
    • React 使用 JSX ,是 JavaScript 和 XML 的混合。
  3. 状态管理:

    • Vue 有内置的状态管理方案 Vuex 。
    • React 常用的状态管理库是 Redux 。
  4. 学习曲线:

    • Vue 相对来说学习曲线较平缓,容易上手。
      React 概念较多,学习曲线相对较陡。

vue

介绍一下微前端

设计模式概述

作为前端架构及管理者的职责

任务分配、基础架构设计