2025前端面试题及答案(详细)

HTML5 的新特性有哪些?

简约版本:

"HTML5 新特性主要体现在六个方面:

第一,语义化标签,比如 header、footer、nav 等,让页面结构更清晰;

第二,表单增强,新增了 date、email 等类型和 placeholder、required 等属性;

第三,多媒体支持,提供了 audio 和 video 标签,不再依赖 Flash;

第四,图形绘制,有 canvas 和 svg;

第五,本地存储,提供了 localStorage 和 sessionStorage;

第六,一些新的 API,比如 WebSocket 实时通信、Web Worker 多线程、地理定位、拖拽 API 和 History API 等。

总体来说,HTML5 更加语义化、增强了交互体验,也提高了性能和可用性。"

详细版本:

主要分为 语义化标签、表单增强、多媒体支持、图形绘制、本地存储、API 六大类:

  1. 语义化标签

    • 新增结构标签:headerfooternavsectionarticleasidemain

    • 作用:提升页面语义,利于 SEO 和可访问性

  2. 表单增强

    • 新的表单控件:dateemailurlnumberrangecolorsearch

    • 新的属性:requiredplaceholderpatternautofocus

  3. 多媒体支持

    • 原生音视频标签:<audio><video>

    • 支持多种格式,不依赖 Flash

  4. 图形绘制

    • canvas:支持 2D 图形绘制

    • svg:矢量图形支持

  5. 本地存储

    • localStorage:长期存储,容量比 cookie 大

    • sessionStorage:会话级存储

  6. 新的 API

    • 地理定位navigator.geolocation

    • 拖放 APIdrag & drop

    • Web Worker:多线程处理

    • WebSocket:双向实时通信

    • History API:控制浏览器历史记录

ARIA / 无障碍开发面试题 & 答案

Q1. 什么是 ARIA?

ARIA(Accessible Rich Internet Applications)是一组 HTML 属性,主要以 aria- 开头。它的作用是帮助辅助技术(比如屏幕阅读器)理解页面结构和交互状态。

在现代前端中,我们经常用自定义组件(比如用 div 模拟按钮),这些元素本身没有语义,屏幕阅读器读不懂。ARIA 就是用来补充语义信息,让页面对残障用户更加友好。

👉 可以补充一句:ARIA 不会改变视觉效果,只影响辅助技术的理解。

Q2. 常见的 ARIA 属性有哪些?举例

**1.角色(role):**定义元素的语义角色,帮助辅助技术识别它是什么。

  • banner(页面头部)

  • navigation(导航区域)

  • main(主要内容)

  • complementary(补充内容)

  • contentinfo(页脚信息)

  • search(搜索区域)

  • button(按钮)

  • checkbox(复选框)

  • radio(单选按钮)

  • tab(选项卡)

  • tabpanel(选项卡面板)

  • tooltip(提示信息)

  • dialog(对话框)

  • article(文章)

  • heading(标题)

  • list(列表)

  • listitem(列表项)

  • table(表格)

  • 等等

2. 状态/属性(aria-*):描述元素当前状态,比如展开/选中/禁用等。

  • aria-label:给元素添加描述信息。

  • aria-hidden:让读屏器忽略某个元素。

  • aria-expanded:表示菜单是否展开。

  • aria-checked:复选框是否选中。

  • aria-live:提示动态区域,读屏器会自动播报内容更新。

html 复制代码
<div role="button" aria-pressed="false" tabindex="0">
  点我
</div>
//role="button" → 让它被识别为按钮
//tabindex="0" → 允许键盘 Tab 聚焦
//aria-pressed="false" → 状态(未按下)

Q3. 开发无障碍应用时,ARIA 和语义化 HTML 有什么关系?

最佳实践是 优先使用语义化 HTML 标签 (比如 <button><nav><header>),因为浏览器和读屏器天然支持。

ARIA 是 补充手段 ,当我们用自定义组件(比如 div 写的按钮)时,再用 rolearia-* 属性来增强可访问性。

一句话总结:能用原生标签就用原生,实在不行才用 ARIA。

Q4. 如何让自定义组件可访问?

  1. 给组件加 role(补充语义)。
  2. aria-* 属性描述状态(比如展开、禁用、选中)。
  3. 确保 键盘可操作 ,加 tabindex="0" 并监听 Enter/Space 键事件。
  4. 动态内容要用 aria-liverole="alert" 提示用户。

👉 这样屏幕阅读器和键盘用户都能正常使用。

Q5. 在实际工作中,你做过哪些可访问性优化?

参考回答:(随便挑 2--3 点说)

  • 用语义化标签代替纯 div/span,比如 <button>

  • 给图片加 alt,给图标加 aria-hidden="true"

  • 自定义组件时,补充 rolearia-* 属性。

  • 处理键盘可访问性(Tab 聚焦、Enter/Space 触发)。

  • 动态提示(比如表单报错)用 aria-live 让读屏器播报。

Q6. ARIA 有什么使用原则?

参考回答:

  • 能用 HTML 原生语义就用原生,不要过度依赖 ARIA。

  • 只在必要时添加,避免属性过多导致读屏器混乱。

  • 测试可访问性:实际用屏幕阅读器(NVDA、VoiceOver)和键盘来测试。

CSS 相关问题

1. CSS 选择器的优先级是怎么计算的?

👉 内联样式 > ID 选择器 > 类 / 属性 / 伪类选择器 > 标签选择器 > 通配符 > 继承 > 浏览器默认样式。

数值记忆法:行内(1000) > ID(100) > 类/伪类(10) > 标签/伪元素(1)。

2. 标准盒模型和 IE 盒模型有什么区别?

👉 标准盒模型:width 只包含 content,不含 padding 和 border。

👉 IE 盒模型:width 包含 content + padding + border。

css 复制代码
元素总宽度 = content + padding + border + margin
元素总高度 = content + padding + border + margin
box-sizing: content-box; /* 标准盒模型(默认) */
box-sizing: border-box;  /* 怪异盒模型 */

3.如何创建响应式布局?

👉 媒体查询(Media Queries):根据不同屏幕宽度设置不同的样式。

css 复制代码
/* 默认样式:移动端优先 */
.container { font-size: 14px; }

/* 平板端 */
@media (min-width: 768px) {
  .container { font-size: 16px; }
}

/* PC 端 */
@media (min-width: 1200px) {
  .container { font-size: 18px; }
}

👉 流式布局(Fluid Layout):使用百分比 %、视口单位 vw/vh、弹性单位 em/rem 等,而不是固定 px

👉 弹性盒子(Flexbox):用 flex 让子元素在父容器中自动适应。

👉网格布局(CSS Grid):Grid 天生适合响应式布局。 自动根据屏幕宽度决定列数。

css 复制代码
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 20px;
}

👉响应式图片 / 媒体:使用 max-width: 100% 让图片不超出容器。

👉移动端适配(viewport 设置):确保在不同设备上缩放正常。

css 复制代码
<meta name="viewport" content="width=device-width, initial-scale=1.0">

移动端优先 是主流做法:先写小屏,再通过媒体查询适配大屏。

4. position 的值有哪几种?区别是什么?

  • static:默认定位,不受 top/left 影响。

  • relative:相对自身定位,占据原位置。

  • absolute:相对最近的非 static 祖先定位。

  • fixed:相对浏览器窗口定位,不随滚动条移动。

  • sticky:结合 relative 和 fixed,根据滚动位置切换。

5. z-index 为什么有时不起作用?

  • 没有定位属性

    • z-index 只在元素设置了定位(position: relative | absolute | fixed | sticky)时才生效。

    • 如果是 position: static(默认),z-index 不会起作用。

  • 层叠上下文(Stacking Context)影响

    • 元素所在的层叠上下文会限制它的 z-index 效果。

    • 每个层叠上下文内部的元素 z-index 只在自己"上下文"里比较,无法跨层叠上下文提升。

    • 触发层叠上下文的情况(常见):

      • 设置了 positionz-index 值不是 auto

      • 设置了 opacity < 1

      • 设置了 transformfilterperspectiveclip-path 等属性;

      • 设置了 isolation: isolate

  • 父子关系影响

    • 子元素的 z-index 受限于父元素所在的层叠上下文,即使子元素 z-index 再大,也不会覆盖在父元素所在层叠上下文之外的兄弟元素之上。
  • 浏览器默认层叠顺序

    • 如果 z-index 相同或没设置,浏览器会按照以下顺序叠放:

      1. 背景和边框(最底层)

      2. z-index 元素

      3. 块级元素(按 HTML 顺序)

      4. 浮动元素

      5. 行内元素(按 HTML 顺序)

      6. z-index 元素(数值越大越靠上)

6.如何实现水平垂直居中?

  • 使用 Flex 布局(推荐 ✅)
css 复制代码
.parent {
  display: flex;
  justify-content: center;  /* 水平居中 */
  align-items: center;      /* 垂直居中 */
}
.child {
  width: 100px;
  height: 100px;
}
  • 使用 Grid 布局
css 复制代码
.parent {
  display: grid;
  place-items: center;  /* 水平 + 垂直居中 */
}
  • 绝对定位 + transform
css 复制代码
.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
  • 绝对定位 + margin auto
css 复制代码
.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 0; bottom: 0;
  left: 0; right: 0;
  margin: auto;
  width: 100px;
  height: 100px;
}
  • 传统方法:表格布局 / line-height
css 复制代码
//第一。表格法(适合文字/小组件):

.parent {
  display: table-cell;
  text-align: center;      /* 水平 */
  vertical-align: middle;  /* 垂直 */
}


// 第二。line-height 法(适合单行文本):

.parent {
  height: 100px;
  line-height: 100px; /* 设置等于高度 */
  text-align: center;
}

**7.**什么是 BFC?有什么作用?

👉定义

  • BFC 全称 Block Formatting Context(块级格式化上下文)

  • 它是页面中的一个独立渲染区域,内部元素的布局不会影响到区域外部。

👉如何触发 BFC(常见几种方式)

  • 设置 float 值(left / right,但不是 none)。

  • 设置 positionabsolute / fixed

  • 设置 displayinline-blocktable-cellflexgrid 等。

  • 设置 overflowhiddenautoscroll

👉 BFC 的特性 / 作用

  • 清除浮动:父元素触发 BFC 后,可以包含子元素的浮动,不会出现高度塌陷。

  • 避免外边距重叠(margin collapse) :同一个 BFC 内的块级元素上下 margin 会重叠,不同 BFC 之间则不会。

  • 隔离作用:BFC 区域和外部独立,内部元素不会影响外部布局。

  • 自适应两栏布局:利用 BFC 可以实现一边浮动一边自适应。

👉 常见应用场景

  • ✅ 清除浮动问题

  • ✅ 阻止 margin 合并

  • ✅ 实现多栏布局(左侧固定宽度,右侧自适应)

JavaScript 作用域 & 闭包

1. 什么是作用域?有哪些类型?

作用域(Scope)是指程序中变量和函数的可访问范围。

JavaScript 的作用域类型主要有:

  1. 全局作用域:在代码最外层声明的变量和函数,整个程序都可以访问。

  2. 函数作用域:每个函数调用时都会创建自己的作用域,函数内部定义的变量只能在函数内部访问。

  3. 块级作用域letconst 声明的变量只在代码块 {} 内有效,例如 if、for 中。

👉 JavaScript 采用 词法作用域(在函数定义时就决定了作用域,而不是运行时)。

2. 什么是作用域链?

当访问一个变量时,JavaScript 引擎会:

  • 先在当前作用域查找

  • 如果找不到,就沿着外层作用域逐级向上查找

  • 直到全局作用域,如果还没找到,就抛出 ReferenceError

这种 逐级查找的链条 就叫 作用域链

👉 本质:函数持有外部作用域的引用

3. 什么是执行上下文(Execution Context)?

执行上下文是 JavaScript 代码运行时的环境。

每次执行一段代码时,都会创建一个执行上下文,包括:

  1. 变量环境(var 声明的变量、函数声明)

  2. 词法环境(let、const 声明的变量)

  3. this 绑定(当前执行环境的 this 指向)

执行上下文分为三类:

  • 全局上下文(页面首次运行时创建,只有一个)

  • 函数上下文(每次调用函数时都会创建)

  • eval 上下文(eval 代码执行时创建,不推荐使用)

4. 什么是变量提升?

JavaScript 在代码执行前,会先进行"预编译"阶段:

  • var 声明的变量会提升到作用域顶端,默认值是 undefined

  • 函数声明(function declaration)会整体提升,可以在声明前调用。

  • letconst 也会提升,但存在 暂时性死区(TDZ),在声明前使用会报错。

css 复制代码
console.log(a); // undefined
var a = 10;

console.log(b); // ReferenceError
let b = 20;

5.this 在不同场景下的指向是什么?

  1. 普通函数调用 → 在非严格模式下指向全局对象(window),严格模式下是 undefined

  2. 对象方法调用 → 指向调用该方法的对象。

  3. 构造函数调用(new) → 指向新创建的实例对象。

  4. 显式绑定 → 使用 callapplybind 可以手动指定 this。

  5. 箭头函数 → 没有自己的 this,继承外层作用域的 this。

6. 什么是闭包?

闭包是指一个函数与其周围的词法环境(变量和状态)的绑定。通过闭包,函数可以访问其外部作用域中的变量,即使在外部函数执行结束后,这些变量依然可以被内部函数访问和使用。

闭包的本质是函数与其定义时的作用域环境的结合。当一个函数返回另一个函数时,返回的内部函数会保留对外部函数作用域的引用,从而形成闭包。

条件(记三个字:函数 + 引用)

  1. 必须有 函数嵌套

  2. 内部函数 用到了外部变量

  3. 外部函数执行完,但变量 仍被引用

作用

  • 数据持久化:能够让某些变量长期保存在内存中,实现状态的记忆。

  • 封装与私有化:利用闭包,可以模拟私有变量,避免外部随意修改。

  • 函数式编程:闭包是实现回调函数、高阶函数、函数工厂等的重要基础。

缺点

(1)容易在循环中出 bug(var 导致所有闭包共享同一个变量)

javascript 复制代码
(1)循环里的闭包问题
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1000);
}
// 输出:3 3 3


原因:var i 是同一个函数作用域,闭包引用的是同一个 i

解决方法:

for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1000);
}
// 输出:0 1 2

或者使用 IIFE(立即执行函数):

for (var i = 0; i < 3; i++) {
  ((i) => {
    setTimeout(() => console.log(i), 1000);
  })(i);
}

(2)内存泄漏

  • 闭包持有外部函数的变量引用,如果使用不当,可能导致内存不能及时释放。

7. 为什么闭包会导致内存泄漏?

因为闭包会让外部函数的变量一直被引用,垃圾回收机制(GC)无法释放这部分内存。

解决方法:

  • 在不需要闭包时,将其引用置为 null

  • 避免过度使用闭包

8. 闭包的实际应用场景有哪些?

(1)封装私有变量

css 复制代码
function Counter() {
  let count = 0;
  return {
    inc: () => ++count,
    dec: () => --count
  };
}

(2)事件处理器(回调函数中访问外部变量)

(3)函数柯里化(currying)

javascript 复制代码
function add(a) {
  return function(b) {
    return a + b;
  };
}

9. 什么是事件循环(Event Loop)?宏任务和微任务有什么区别?

JavaScript 是单线程的,采用 事件循环机制 来处理异步任务。

执行顺序:

  1. 先执行 同步代码(主线程)。

  2. 同步执行完后,检查 微任务队列(microtask queue),依次执行完。

  3. 微任务清空后,再执行一个 宏任务(macrotask)

  4. 重复以上过程,形成循环。

常见宏任务(macrotask): setTimeoutsetIntervalsetImmediate、I/O、UI 渲染。
常见微任务(microtask): Promise.then/catch/finallyMutationObserverqueueMicrotaskprocess.nextTick(Node)

👉 口诀:先同步 → 再微任务 → 再宏任务

10. 什么是原型和原型链?

  • 原型(prototype)

    每个函数都有一个 prototype 属性,用于存放实例共享的方法和属性。

  • 原型链 (Prototype Chain):

    对象在查找属性时,会先在自己本身查找,如果没有,就沿着 __proto__ 向上查找父级原型,直到 Object.prototype,再到 null 停止。

javascript 复制代码
function Person() {}
const p = new Person();
console.log(p.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true

👉 原型链的本质是 对象属性查找机制

11. async / await 的底层原理是什么?

  • async/awaitES2017 引入的语法糖,用来写异步代码。

  • async 函数默认返回一个 Promise

  • await 用来等待一个 Promise 的结果,函数会"暂停"执行,等结果出来再继续。

  • 👉 作用:让异步代码写起来更像同步代码,可读性更好。

底层原理:

  1. async/awaitPromise 的语法糖,本质是基于 Promise + Generator 实现的。

  2. await 会暂停函数的执行,把后续代码放进微任务队列,等 Promise 完成后再继续执行。

👉 关键点:await 会把后续代码放到 微任务队列

12. Promise 是什么?解决了什么问题?

  • Promise 是 ES6 引入的一种 异步编程的解决方案,用于表示一个可能在未来某个时间点才会完成的操作结果。

  • 本质是一个 状态机 ,有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败),且状态 不可逆

  • Promise 提供了统一的 .then/.catch/.finally 接口,使得我们可以通过链式调用来组织异步代码。

解决的问题:

(1)回调地狱(Callback Hell)

  • 传统异步依赖多层嵌套回调,代码难以维护;

  • Promise 通过链式调用让异步逻辑更加扁平化、清晰。

(2)错误处理分散

  • 回调模式下错误需要逐层处理;

  • Promise 支持 错误冒泡 ,集中用 .catch 捕获异常。

(3)异步流程控制

  • Promise.all / race / allSettled / any 提供了强大的并发控制能力,方便管理多个异步任务。
相关推荐
群联云防护小杜11 小时前
服务器异常负载排查手册 · 隐蔽进程篇
运维·服务器·前端·数据库·笔记·sql·tcp/ip
小小菜鸡ing11 小时前
简单爬一个小说页面 HTML 的title和内容
前端·html
IT_陈寒11 小时前
Spring Boot 3 + GraalVM:5个实战技巧让Java应用启动速度提升300%
前端·人工智能·后端
前端世界12 小时前
前端跨域终极指南:3 种优雅解决方案 + 可运行 Demo
前端·javascript·状态模式
无奈何杨12 小时前
CoolGuard风控系统配置评分卡、权重策略|QLExpress脚本
前端·后端
几度风雨见丹心12 小时前
vue+elementUI 进行表格行内新增及校验,同行其他输入框数据影响当前输入框校验结果
前端·vue.js·elementui
开发者小天12 小时前
在Ant Design Vue 中使用图片预览的插件
前端·javascript·vue.js·前端框架
华科云商xiao徐12 小时前
手把手教你用Go打造带可视化的网络爬虫
前端·爬虫
_月下闲人12 小时前
已掌握 Vue2 的开发者,快速上手 Vue3
前端·javascript·vue.js