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 提供了强大的并发控制能力,方便管理多个异步任务。
相关推荐
崔庆才丨静觅8 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60619 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了9 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅9 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅9 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅10 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment10 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅10 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊10 小时前
jwt介绍
前端
爱敲代码的小鱼10 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax