写在前面
本次面试不仅是对基础知识的常规检验,更是一次对前端技术体系完整性的深度拷问。
从 ES6+ 现代语法特性 的灵活应用,深入到 Promise 异步状态机 与 执行上下文 的底层原理;从 Tailwind CSS 代表的工程化权衡,延伸至 浏览器渲染管线 与 网络协议 的宏观视野。特别是在面对 Promise 链式调用机制与箭头函数本质差异等“深水区”问题时,暴露出的认知盲区成为了本次复盘的关键突破口。
本文旨在系统梳理此次面试真题,将零散的知识点重构为逻辑严密的技术图谱,通过对“为什么”的深层追问,填补原理认知的缺口,为后续的技术进阶夯实根基。
ES6 新语法
- 变量声明:
let和const(具有块级作用域,不存在变量提升)。 - 解构赋值: 快速从数组或对象中提取值。
- 模板字符串: 使用反引号 (
`) 和${}进行字符串拼接。 - 展开运算符 (...): 用于合并数组或拷贝对象。
- 类 (Class): 语法糖,让 JavaScript 的继承更接近传统面向对象语言。
- 模块化 (Import/Export): 官方标准的模块导入导出方案。
- 箭头函数:不仅简化了写法,它还通过词法作用域绑定了
this,这在处理回调函数和数组方法时极大地减少了上下文丢失的困扰。
Promise 是如何实现异步编程并支撑链式调用 没答出来
- 实现原理: Promise 是一个状态机,有三个状态:
Pending(进行中)、Fulfilled(已成功)和Rejected(已失败)。状态一旦改变就不可逆。 - 链式调用:
promise.then()会返回一个新的 Promise 实例,这使得我们可以像链条一样连续调用.then()。如果前一个then返回的是一个普通值,它会被封装成已成功的 Promise;如果返回的是另一个 Promise,后续的then会等待这个新的 Promise 状态改变后再执行。
箭头函数与普通函数的区别 没答出来
- this 指向: 普通函数的
this指向调用它的对象;箭头函数没有自己的 this,它会捕获所在上下文的this。 - 构造函数: 箭头函数不能用作构造函数,即不能使用
new关键字。 - arguments: 箭头函数没有自己的
arguments对象。 - 原型: 箭头函数没有
prototype属性。
JS 执行栈与执行上下文
- 执行上下文 (Execution Context): JS 环境的抽象概念,包含当前代码运行所需的变量、函数声明、
this等。主要有全局上下文和函数上下文。 - 执行栈 (Execution Stack): 也叫调用栈,是一种 后进先出 (LIFO) 的数据结构。当函数被调用时,会创建一个新的上下文并压入栈顶;函数执行完毕后,该上下文从栈中弹出。
Tailwind CSS 的优劣及 CSS 工程化
- Tailwind CSS 好处: 开发速度快(无需离开 HTML 写 CSS)、高度可定制、原子类设计减少了 CSS 体积(配合 PurgeCSS)、易于保持设计一致性。
- 坏处: 初始学习成本、HTML 类名非常臃肿、需要构建工具支持。
- CSS 工程化: 了解预处理器(Sass/Less)、后处理器(PostCSS)、CSS Modules(解决命名冲突)以及 CSS-in-JS(如 Styled Components)。
从 URL 到页面显示的渲染过程
这是一个经典链路问题:
- 网络请求: DNS 解析 -> TCP 握手 -> 发送 HTTP 请求 -> 服务器响应。
- 解析: 浏览器解析 HTML 生成 DOM 树,解析 CSS 生成 CSSOM 树。
- 渲染树: 将 DOM 和 CSSOM 合并生成 Render Tree。
- 布局 (Layout): 计算每个节点在屏幕上的确切位置和大小。
- 绘制 (Paint): 将节点像素绘制到屏幕上。
- 合成 (Compositing): 将不同层级的内容合并显示。
重绘 (Repaint) 与 重排 (Reflow) 的区别
- 重排 (Reflow/Layout): 当元素的几何属性(如宽、高、位置、隐藏显示等)发生改变,浏览器需要重新计算元素位置并重新构建渲染树。性能开销大。
- 重绘 (Repaint): 当元素的外观属性(如颜色、背景色、visibility 等)发生改变,但不影响布局时,浏览器直接重新绘制元素。重排一定会引起重绘,但重绘不一定引起重排。