跳到主要内容
前端知识点全解析 | 极客日志
Python
前端知识点全解析 作为一名前端高级开发人员,面试不仅考察知识点的记忆,更关注对原理的理解、工程化的思考以及解决复杂问题的能力。将从 HTML/CSS、JavaScript、浏览器与网络、框架、工程化、性能优化、算法与设计模式等多个维度,系统梳理前端面试中的核心知识点,并提供深入解析及案例,帮助你在面试中展现出真正的技术深度。 * * 1\. HTML & CSS 基础 1.1 语义化 HTML **讲解**:语…
AiEngineer 发布于 2026/4/6 更新于 2026/5/24 87K 浏览作为一名前端高级开发人员,面试不仅考察知识点的记忆,更关注对原理的理解、工程化的思考以及解决复杂问题的能力。本文将从 HTML/CSS、JavaScript、浏览器与网络、框架、工程化、性能优化、算法与设计模式等多个维度,系统梳理前端面试中的核心知识点,并提供深入解析及案例,帮助你在面试中展现出真正的技术深度。
1. HTML & CSS 基础
1.1 语义化 HTML
讲解 :语义化 HTML 是指使用具有明确含义的标签(如 <header>、<nav>、<article>、<section>)来描述网页结构,而不是单纯使用 <div> 和 <span>。
解析 :
SEO 友好 :搜索引擎爬虫依赖语义标签理解页面内容,有助于提升排名。
可访问性 :屏幕阅读器等辅助技术可以更好地解析页面,为视障用户提供良好体验。
代码可维护性 :团队协作时,语义化标签让代码结构清晰易懂。
常见语义标签 :<header>、<footer>、<main>、<aside>、<article>、<section>、<nav>。
案例 :
<divclass="header"><divclass="logo">MySite</div > <divclass="nav"><ahref="/">首页</a > <ahref="/about">关于</a > </div > </div > <header > <h1class="logo">MySite</h1 > <nav > <ul > <li > <ahref="/">首页</a > </li > <li > <ahref="/about">关于</a > </li > </ >
ul
</nav >
</header >
面试题 :<b> 和 <strong> 的区别?
解析 :<b> 仅表示粗体样式,无语义;<strong> 表示强调内容,有语义,屏幕阅读器会以重音读出。
1.2 盒模型 讲解 :CSS 盒模型描述了一个元素所占空间的结构,包括内容(content)、内边距(padding)、边框(border)、外边距(margin)。
标准盒模型 :width/height 只包含内容区,不包含 padding 和 border。总宽度 = width + padding + border + margin。
IE 盒模型 (怪异盒模型):width/height 包含内容、padding 和 border。总宽度 = width + margin。
切换方式 :通过 box-sizing: content-box(默认)或 box-sizing: border-box 设置。
实际应用 :通常将 box-sizing 设置为 border-box 更易于布局,避免频繁计算宽高。
.box-standard {box-sizing : content-box;width : 100px ;padding : 10px ;border : 5px solid black;margin : 10px ;}.box-border {box-sizing : border-box;width : 100px ;padding : 10px ;border : 5px solid black;margin : 10px ;}
1.3 布局方式
1.3.1 浮动与清除浮动 讲解 :float 使元素脱离文档流,向左或向右浮动,常用于文字环绕图片或实现多列布局。
浮动影响 :父容器高度塌陷(因为浮动元素不占文档流高度)。
清除浮动方法 :
在父容器末尾添加空元素并设置 clear: both。
父容器触发 BFC(如 overflow: hidden)。
使用伪元素:.clearfix::after { content: ""; display: table; clear: both; }。
<divclass="container clearfix"><divclass="float -left ">浮动元素</div ><divclass="float -left ">浮动元素</div ></div ><style>.float-left {float : left;width : 100px ;height : 100px ;background : lightblue;}.clearfix ::after {content :"" ;display : table;clear : both;}</style>
1.3.2 定位 讲解 :position 属性控制元素的定位方式,包括 static、relative、absolute、fixed、sticky。
relative:相对自身原本位置偏移,仍占文档流空间。
absolute:相对最近的非 static 祖先元素定位,脱离文档流。
fixed:相对视口定位,脱离文档流。
sticky:粘性定位,根据滚动阈值在 relative 和 fixed 之间切换。
层叠上下文 :z-index 仅在非 static 定位元素上生效,且受层叠上下文影响。
<divclass="parent"style="position : relative;height : 200px ;background : #eee ;"><divclass="child"style="position : absolute;bottom : 10px ;right : 10px ;">绝对定位</div ></div ><divclass="sticky"style="position : sticky;top : 0 ;">粘性头部</div >
1.3.3 Flex 布局 讲解 :Flex 是一维布局模型,提供强大的对齐和空间分配能力。
容器属性 :display: flex;flex-direction(主轴方向);justify-content(主轴对齐);align-items(交叉轴对齐);flex-wrap(换行)。
项目属性 :flex-grow(放大比例)、flex-shrink(缩小比例)、flex-basis(初始大小);align-self(覆盖容器的 align-items)。
经典应用 :垂直居中(justify-content: center; align-items: center)、圣杯布局、等分布局。
.container {display : flex;justify-content : space-between;align-items : center;height : 200px ;}.item {flex : 1 ;margin : 10px ;}
1.3.4 Grid 布局 讲解 :Grid 是二维布局模型,将容器划分为行和列,可精确控制元素位置。
容器属性 :display: grid;grid-template-rows/columns 定义行/列轨道;gap 间隙;justify/align-items 控制单元格内对齐。
项目属性 :grid-row/column 指定项目占据的网格线;justify/align-self 控制项目自身对齐。
与 Flex 区别 :Grid 适合整体页面布局,Flex 适合组件内部的一维排列。
.grid-container {display : grid;grid-template-columns : 1 fr 2 fr 1 fr;grid-template-rows : 100px 200px ;gap : 10px ;}.item {background : lightcoral;}.item :first-child {grid-column : 1 / 3 ;}
1.4 响应式设计 讲解 :响应式设计使网站在不同设备(手机、平板、桌面)上都能良好显示。
视口(viewport) :通过 <meta name="viewport" content="width=device-width, initial-scale=1"> 设置,确保页面宽度适配设备宽度。
媒体查询 :@media (max-width: 768px) { ... } 根据屏幕尺寸应用不同样式。
相对单位 :em(相对于父元素字体)、rem(相对于根元素字体)、vw/vh(视口宽高百分比)、%。
弹性布局 :结合 Flex/Grid 实现容器自适应。
图片响应式 :srcset 和 sizes 属性或 <picture> 元素,根据分辨率加载合适图片。
<imgsrcset="small.jpg 300 w, medium.jpg 600 w, large.jpg 900 w"sizes="(max-width: 600px ) 100vw , (max-width: 900px ) 50vw , 33vw "src ="large.jpg "alt="响应式图片"><style>.container {width : 80% ;margin : 0 auto;}@media (max-width : 768px ){.container {width : 100% ;padding : 0 10px ;}}</style>
1.5 CSS 预处理器 讲解 :Sass、Less 等预处理器为 CSS 提供了变量、嵌套、混合、继承等编程特性。
变量 :$primary-color(Sass)或 @primary-color(Less),便于主题管理。
嵌套 :减少重复父选择器,但避免过深嵌套。
混合(mixin) :可复用样式块,可传参。
函数与运算 :颜色函数、数学运算。
模块化 :@import 分割文件,最终编译为一个 CSS 文件。
$primary: #007bff ; $spacing: 1rem ; @mixin rounded($radius : 4px ) { border-radius : $radius; } .button { background : $primary; padding : $spacing/2 $spacing; @include rounded(8px ); &:hover { background : darken ($primary, 10% ); } }
1.6 BEM 命名规范 讲解 :BEM(Block Element Modifier)是一种 CSS 命名方法论,旨在提高代码可读性和可维护性。
Block :独立实体,如 .header、.menu。
Element :属于块的一部分,如 .header__logo、.menu__item。
Modifier :修饰块或元素的状态,如 .header--fixed、.menu__item--active。
优点 :避免样式冲突,清晰的结构关系。
<divclass="card" ><divclass="card__header" ><h2class="card__title" >标题</h2></div><divclass="card__body" >内容</div><divclass="card__footer card__footer--highlighted" >底部高亮</div></div><style>.card__footer--highlighted{background: yellow;}</style>
1.7 层叠上下文与 z-index 讲解 :层叠上下文是 HTML 元素在 Z 轴上的层级概念,z-index 决定同一层叠上下文中元素的堆叠顺序。
创建层叠上下文的条件 :根元素、position 非 static 且 z-index 值不为 auto、opacity 小于 1、transform 非 none、filter 非 none 等。
z-index 比较 :只有同一层叠上下文内的元素才能比较 z-index;不同上下文中,父级上下文决定层级。
常见问题 :明明设置了很大的 z-index 却无效,通常是因为元素不在同一个层叠上下文,或父级 z-index 限制。
<divstyle="position : relative;z-index : 1 ;"><divstyle="position : absolute;z-index : 999 ;">这个999 受父级1 限制</div ></div ><divstyle="position : relative;z-index : 2 ;"><divstyle="position : absolute;z-index : 1 ;">这个1 比上面的999 大,因为父级z-index =2 更高</div ></div >
2. JavaScript 核心
2.1 数据类型与类型判断 讲解 :JavaScript 有 8 种数据类型:undefined、null、boolean、number、string、symbol(ES6)、bigint(ES11)、object。其中前 7 种为原始类型,object 为引用类型。
类型判断方法 :
typeof:适合原始类型,但 typeof null === 'object'(历史遗留 bug),typeof function(){} === 'function'。
instanceof:检查对象原型链,用于判断引用类型。
Object.prototype.toString.call():最准确,返回 [object Type]。
隐式类型转换 :+、== 等操作符会触发类型转换,需注意规则(如 [] == ![] 结果为 true)。
console.log(typeof42);// "number" console.log(typeof'hello' );// "string" console.log(typeoftrue);// "boolean" console.log(typeofundefined);// "undefined" console.log(typeofnull);// "object" (历史遗留) console.log(typeof{});// "object" console.log(typeoffunction(){});// "function" console.log([]instanceofArray);// true console.log({}instanceofObject);// true console.log(Object .prototype.toString.call([]));// "[object Array]" console.log(Object .prototype.toString.call(null));// "[object Null]"
2.2 作用域与闭包 讲解 :作用域决定了变量的可访问范围。JavaScript 采用词法作用域(静态作用域),函数的作用域在定义时确定。闭包是指有权访问另一个函数作用域中变量的函数。
作用域链 :当访问变量时,从当前作用域开始向上查找,直到全局。
闭包的形成 :内部函数引用了外部函数的变量,即使外部函数执行完毕,变量仍被内部函数引用,不会被垃圾回收。
常见用途 :
封装私有变量(模块模式)。
函数柯里化。
循环中使用 var 创建多个闭包(通常用 IIFE 或 let 解决)。
内存泄漏 :闭包不当会导致内存无法释放,应避免无限制使用。
// 闭包封装私有变量functioncreateCounter(){let count =0 ;return {increment:()=>++count,decrement:()=>--count,getCount:()=> count };}const counter =createCounter(); console.log(counter.increment());// 1 console.log(counter.increment());// 2 console.log(counter.getCount());// 2
2.3 原型与原型链 讲解 :JavaScript 通过原型实现继承。每个对象都有一个 __proto__ 属性指向其构造函数的原型对象 prototype。原型链由多个对象的 __proto__ 链接而成。
构造函数 :函数本身也是对象,拥有 prototype 属性。通过 new 调用构造函数创建实例,实例的 __proto__ 指向构造函数的 prototype。
原型链查找 :访问对象属性时,如果对象自身没有,则沿着 __proto__ 向上查找,直到 null。
原型链终点 :Object.prototype.__proto__ === null。
继承方式 :
原型链继承:Child.prototype = new Parent()。
组合继承:原型链 + 构造函数。
ES6 class 语法糖(本质仍是原型链)。
instanceof 原理 :检测右侧构造函数的 prototype 是否在左侧对象的原型链上。
functionAnimal(name){this.name = name;}Animal.prototype.speak=function () { console.log (`${this.name} makes a sound.`);};functionDog(name, breed){Animal.call(this, name);// 借用构造函数this.breed = breed;}// 原型链继承Dog.prototype = Object.create (Animal.prototype);Dog.prototype.constructor = Dog;Dog.prototype.bark=function () { console.log (`${this.name} barks.`);};const d =newDog('Rex' ,'Husky' ); d.speak();// Rex makes a sound. d.bark();// Rex barks. console.log (d instanceofDog);// true console.log (d instanceofAnimal);// true
2.4 this 指向与 call/apply/bind 讲解 :this 的值在函数调用时确定,取决于调用方式。
默认绑定 :独立函数调用,this 指向全局对象(浏览器中为 window),严格模式为 undefined。
隐式绑定 :作为对象方法调用,this 指向该对象。
显式绑定 :call、apply、bind 可以强制指定 this。
call(thisArg, arg1, arg2...):立即执行,参数列表。
apply(thisArg, [arg1, arg2...]):立即执行,参数数组。
bind(thisArg, arg1, arg2...):返回新函数,永久绑定 this。
new 绑定 :使用 new 调用构造函数,this 指向新创建的对象。
箭头函数 :没有自己的 this,捕获外层作用域的 this(词法绑定)。
优先级 :new > 显式绑定 > 隐式绑定 > 默认绑定。
functiongreet(greeting, punctuation){ console.log(greeting +', ' +this.name + punctuation);}const person ={name:'Alice' };greet.call(person,'Hello' ,'!' );// Hello, Alice!greet.apply(person,['Hi' ,'?' ]);// Hi, Alice?const bound =greet.bind(person,'Hey' );bound('!!' );// Hey, Alice!!
2.5 异步编程
2.5.1 回调函数
优点 :简单直观。
缺点 :回调地狱(多层嵌套)、错误处理困难、代码可读性差。
functionfetchData (callback){setTimeout (()=>{callback ('data');},1000 );}fetchData ((result)=>{ console.log (result);});
2.5.2 Promise 讲解 :Promise 是异步编程的解决方案,代表一个最终完成或失败的操作。
状态 :pending(进行中)、fulfilled(已成功)、rejected(已失败)。状态一旦改变不可逆。
实例方法 :
then(onFulfilled, onRejected):返回新 Promise,支持链式调用。
catch(onRejected):相当于 .then(null, onRejected)。
finally(onFinally):无论成功失败都会执行。
静态方法 :
Promise.all(iterable):全部成功才成功,任一失败则立即失败。
Promise.race(iterable):首个状态变更的 Promise 决定结果。
Promise.allSettled(iterable):等待所有完成,返回每个结果(fulfilled/rejected)。
Promise.any(iterable):首个成功的结果,若全部失败则 AggregateError。
错误处理 :Promise 链中通过 catch 捕获错误,注意在 then 中抛出的错误也会被后续 catch 捕获。
functionasyncTask (shouldResolve){returnnewPromise ((resolve, reject )=> {setTimeout (()=> { shouldResolve ?resolve ('成功' ):reject ('失败' );},1000 );});}asyncTask (true ).then (result => console .log (result)).catch (error => console .error (error)); Promise .all ([asyncTask (true ),asyncTask (true )]).then (results => console .log ('全部成功' , results)).catch (err => console .error ('至少一个失败' , err));
2.5.3 async/await 讲解 :async/await 是 ES2017 引入的语法糖,基于 Promise,使异步代码像同步一样书写。
async 函数 :返回一个 Promise,内部返回值会被 Promise.resolve() 包装。
await 表达式 :等待一个 Promise 完成,会暂停当前 async 函数的执行,直到 Promise 状态变为 fulfilled 或 rejected。
错误处理 :使用 try/catch 捕获 await 中 Promise 的 reject。
注意事项 :await 只能在 async 函数中使用;多个无依赖的异步操作应使用 Promise.all 并发执行,避免串行等待。
asyncfunctionfetchData (){try{const result =awaitasyncTask (true); console.log (result);const data =awaitasyncTask (true); console.log (data);}catch (error){ console.error ('捕获错误:', error);}}fetchData ();
2.6 事件循环与宏任务/微任务 讲解 :JavaScript 是单线程语言,通过事件循环机制处理异步任务。任务分为宏任务(macrotask)和微任务(microtask)。
宏任务 :script 整体代码、setTimeout、setInterval、I/O、UI 渲染等。
微任务 :Promise.then/catch/finally、MutationObserver、queueMicrotask、process.nextTick(Node)。
执行顺序 :
执行当前宏任务(如 script 整体)。
执行所有微任务(清空微任务队列)。
取出下一个宏任务执行,重复。
console .log ('1' );setTimeout (()=> console .log ('2' ),0 ); Promise .resolve ().then (()=> console .log ('3' )); console .log ('4' );
console .log ('start' );setTimeout (()=> console .log ('timeout' ),0 ); Promise .resolve ().then (()=> console .log ('promise1' )); Promise .resolve ().then (()=> { console .log ('promise2' );setTimeout (()=> console .log ('timeout inside promise' ),0 );}); console .log ('end' );
2.7 深拷贝与浅拷贝 讲解 :浅拷贝只复制对象的第一层属性,引用类型仍共享引用;深拷贝递归复制所有层级,生成独立对象。
浅拷贝方法 :Object.assign()、扩展运算符 {...obj}、Array.prototype.slice()。
深拷贝方法 :
JSON.parse(JSON.stringify(obj)):缺点是无法处理函数、undefined、Symbol、循环引用。
递归实现(需处理各种数据类型)。
使用结构化克隆:structuredClone()(现代浏览器支持)。
第三方库如 Lodash 的 _.cloneDeep。
性能考量 :深拷贝成本高,应根据场景选择。
const original ={a :1 ,b:{c:2 }};// 浅拷贝const shallow ={...original }; shallow.b .c =3 ; console.log (original.b .c );// 3 (相互影响)// 深拷贝const deep =JSON.parse (JSON.stringify (original)); deep.b .c =4 ; console.log (original.b .c );// 3 (独立)
2.8 防抖与节流 节流(throttle) :规定一个单位时间内,只能触发一次函数。适用于滚动加载、频繁点击。
functionthrottle (fn, interval){let lastTime =0 ;returnfunction (...args){const now = Date.now ();if (now - lastTime >= interval){fn.apply (this, args); lastTime = now;}};}
防抖(debounce) :在事件被触发 n 秒后执行回调,如果在这 n 秒内又被触发,则重新计时。适用于输入框搜索、窗口 resize。
functiondebounce (fn, delay){let timer =null;returnfunction (...args){clearTimeout (timer); timer =setTimeout (()=>fn.apply (this, args), delay);};}
<inputid="search" type ="text" placeholder="搜索" ><script > const input = document .getElementById ('search' ); input.addEventListener ('input' ,debounce (function (e ){ console .log ('发送请求:' , e.target .value );},500 ));</script >
2.9 数组/对象常用方法 讲解 :掌握 ES5/ES6 中数组和对象的常用方法。
数组方法 :
迭代:forEach、map、filter、reduce、some、every。
查找:indexOf、find、findIndex、includes。
增删改:push/pop、shift/unshift、splice、concat、slice。
排序/反转:sort、reverse。
扁平化:flat、flatMap。
对象方法 :
遍历:Object.keys()、Object.values()、Object.entries()。
拷贝/合并:Object.assign()。
创建:Object.create()(指定原型)。
属性描述符:Object.defineProperty()。
// 数组const arr =[1,2,3,4] ;const doubled = arr.map (x => x *2 );// [2,4,6,8] const evens = arr.filter (x => x %2 ===0 );// [2,4] const sum = arr.reduce ((acc, cur)=> acc + cur,0 );// 10 // 对象const obj ={a :1 ,b:2 }; Object .keys (obj).forEach (key=> console.log (key, obj[key] ));const merged = Object .assign ({}, obj,{c:3 });// {a :1 ,b:2 ,c:3 }
3. 浏览器与网络
3.1 浏览器渲染原理 讲解 :浏览器从获取 HTML 到渲染出页面的过程。
解析 HTML :构建 DOM 树。
解析 CSS :构建 CSSOM 树。
合并 :生成渲染树(Render Tree),只包含可见节点。
布局(Layout/Reflow) :计算每个节点的几何位置。
绘制(Paint) :将渲染树绘制到屏幕。
合成(Composite) :分层绘制,利用 GPU 加速。
关键点 :CSS 不会阻塞 DOM 解析,但会阻塞渲染;JS 会阻塞 DOM 解析(除非标记 async 或 defer)。
<scriptsrc="slow.js"></script > <scriptasyncsrc="async.js"></script > <scriptdefersrc="defer.js"></script >
3.2 回流与重绘 讲解 :回流(Reflow)指元素的几何属性(尺寸、位置)发生变化,需要重新计算布局;重绘(Repaint)指元素样式改变但不影响布局(如颜色、背景)。
触发回流的操作 :添加/删除 DOM、修改元素尺寸、页面初始渲染、窗口大小变化、获取某些属性(如 offsetWidth)时可能强制同步布局。
优化策略 :
批量修改样式(使用 class 或 cssText)。
将元素脱离文档流(position: absolute)后再操作。
使用 requestAnimationFrame 读写 DOM。
避免频繁读取布局属性。
// 避免多次触发回流const div = document.getElementById('box' ); div.style.width ='100px' ;// 回流 div.style.height ='100px' ;// 再次回流// 优化:合并修改 div.style.cssText ='width: 100px; height: 100px;' ;// 或使用class div .classList .add ('big -box ') ;
3.3 跨域解决方案 讲解 :同源策略限制不同源(协议、域名、端口任一不同)的资源交互。跨域指突破此限制进行通信。
JSONP :利用 <script> 标签没有跨域限制,通过动态创建 script 加载带回调函数名的 URL。仅支持 GET。
CORS (跨域资源共享):服务器设置响应头 Access-Control-Allow-Origin 允许特定来源。支持所有 HTTP 方法。
简单请求和非简单请求(需预检请求 OPTIONS)。
代理服务器 :开发环境下配置 webpack-dev-server 的 proxy,或 Nginx 反向代理。
postMessage :用于 iframe 或窗口间通信。
WebSocket :不受同源策略限制。
document.domain :适用于主域相同子域不同的情况(已过时)。
/ / JSONPfunctionjsonp(url, callbackName){const script = document.createElement('script' ); script.src = `${url}?callback= ${callbackName}`; window [callbackName]= (data)= > { console.log ('接收数据:' , data);delete window [callbackName]; document.body.removeChild(script);}; document.body.appendChild(script);}jsonp('http://api.example.com/data' ,'handleData' );/ / CORS: 服务器设置响应头 Access- Control- Allow- Origin: *
3.4 HTTP 协议 讲解 :HTTP 是 Web 基础协议,经历了多个版本演进。
HTTP/1.0 :每个 TCP 连接只能发送一个请求,请求结束立即关闭,效率低。
HTTP/1.1 :
持久连接(keep-alive),允许多个请求复用同一个 TCP 连接。
管道化(pipelining),但队头阻塞问题仍存在(必须按顺序响应)。
增加了 Host 头、缓存控制(Cache-Control)等。
HTTP/2.0 :
二进制分帧层,将请求/响应分割为帧,实现多路复用(一个连接同时处理多个请求,解决队头阻塞)。
头部压缩(HPACK),减少开销。
服务器推送(server push)。
HTTP/3.0 :基于 QUIC 协议(UDP),解决 TCP 队头阻塞,更快建立连接。
// HTTP/ 2 服务器推送示例(需服务器支持)// 在响应头中推送关键资源Link:</styles .css>; rel=preload;as=style
3.5 缓存机制 讲解 :浏览器缓存分为强缓存和协商缓存,减少网络请求,提高加载速度。
强缓存 :
Expires:HTTP/1.0 头,绝对时间,依赖客户端时间。
Cache-Control:HTTP/1.1 头,优先级高,常用值 max-age=秒。
协商缓存 :
Last-Modified / If-Modified-Since:资源最后修改时间,可能不准确(如文件修改但内容未变)。
ETag / If-None-Match:资源唯一标识(哈希),更精确。
缓存位置 :Service Worker、Memory Cache、Disk Cache、Push Cache。
缓存策略 :HTML 通常协商缓存或禁用缓存;CSS/JS/图片设置强缓存,并配合文件名哈希更新。
<metahttp-equiv="Cache-Control"content="no-cache, no-store, must-revalidate"/>
3.6 Web 安全
3.6.1 XSS(跨站脚本攻击) 讲解 :攻击者注入恶意脚本到可信网站,当用户浏览时执行。
反射型 :恶意脚本通过 URL 参数注入,后端未过滤直接返回。
存储型 :恶意脚本存储在服务器数据库,如评论区,每次访问都触发。
DOM 型 :纯前端漏洞,通过修改 DOM 执行脚本。
防御 :
输入过滤(对用户输入进行转义)。
输出编码(使用 textContent 而不是 innerHTML)。
设置 Content-Security-Policy(CSP)限制资源加载。
使用 HttpOnly Cookie 防止 Cookie 被脚本窃取。
// 防御:对用户输入进行转义functionescapeHTML(str){return str.replace(/[&<>"]/g ,function(m){if (m ==='&' )return '&' ;if (m ==='<' )return '<' ;if (m ==='>' )return '>' ;if (m ==='"' )return '"' ;return m;});}const userComment ='<script>alert(1)</script>' ; document.getElementById('comment' ).textContent =escapeHTML(userComment);
3.6.2 CSRF(跨站请求伪造) 讲解 :攻击者诱导用户访问第三方网站,利用用户的登录态向目标网站发起恶意请求。
防御 :
使用 CSRF Token:表单中嵌入随机 token,服务端验证。
SameSite Cookie 属性:设置为 Strict 或 Lax,限制跨站发送 Cookie。
验证 Referer 或 Origin 头。
使用验证码(重要操作)。
// 设置SameSite Cookie document.cookie ="session=abc123; SameSite=Lax; Secure"
4. 前端框架(以 Vue 为例)
4.1 Vue 核心概念 讲解 :Vue 是一套用于构建用户界面的渐进式框架,采用组件化、声明式编程。
组件 :Vue 组件由模板、脚本、样式组成,可以是选项式 API 或组合式 API。
模板语法 :基于 HTML 的模板,使用指令(如 v-bind、v-if、v-for)和插值 {{ }}。
响应式系统 :Vue 通过依赖追踪,在数据变化时自动更新视图。Vue 2 使用 Object.defineProperty,Vue 3 使用 Proxy。
实例 :每个 Vue 应用通过 createApp 创建根实例。
生命周期 :组件从创建到销毁的各个阶段,如 created、mounted、updated、unmounted。
<template > <div > <p > {{ message }}</p > <button @click ="reverseMessage" > 反转消息</button > </div > </template > <script > export default { data ( ) { return { message : 'Hello Vue!' }; }, methods : { reverseMessage ( ) { this .message = this .message .split ('' ).reverse ().join ('' ); } } }; </script >
4.2 生命周期与组合式 API 讲解 :Vue 组件有生命周期钩子,组合式 API(Composition API)提供了更灵活的代码组织方式。
选项式 API 生命周期 :
beforeCreate、created(实例创建前后)
beforeMount、mounted(挂载前后)
beforeUpdate、updated(更新前后)
beforeUnmount、unmounted(卸载前后)
组合式 API :
setup 函数是组合式 API 的入口,在 beforeCreate 之前执行。
响应式数据:ref、reactive。
生命周期钩子:onMounted、onUpdated、onUnmounted 等。
计算属性:computed。
侦听器:watch、watchEffect。
优势 :更好的逻辑复用、类型推导、代码组织。
<template > <div > <p > 计数: {{ count }}</p > <button @click ="increment" > +1</button > </div > </template > <script setup > import { ref, onMounted } from 'vue' ; const count = ref (0 ); function increment ( ) { count.value ++; } onMounted (() => { console .log ('组件已挂载' ); }); </script >
4.3 虚拟 DOM 与 Diff 算法 讲解 :Vue 通过虚拟 DOM 描述真实 DOM 结构,在数据变化时生成新的虚拟 DOM,与旧虚拟 DOM 进行 Diff 比较,找出最小更新范围,然后批量更新真实 DOM。
Vue 的 Diff 策略 (基于 Snabbdom):
同层比较,不跨级复用。
通过 key 优化列表渲染,识别节点移动、添加、删除。key 应稳定、唯一,避免使用索引。
双端比较算法(Vue 2)或快速 Diff(Vue 3),提升性能。
Vue 3 优化 :静态树提升、静态属性提升、事件缓存等,减少更新开销。
<template > <ul > <li v-for ="item in items" :key ="item.id" > {{ item.name }}</li > </ul > </template > <script setup > import { ref } from 'vue' ; const items = ref ([ { id : 1 , name : '苹果' }, { id : 2 , name : '香蕉' } ]); </script >
4.4 状态管理 讲解 :随着应用规模增大,需要统一管理共享状态。Vue 官方推荐 Vuex(Vue 2)或 Pinia(Vue 3)。
Vuex :
核心概念:state(状态)、getters(派生状态)、mutations(同步修改)、actions(异步操作)、modules(模块)。
原则:状态变更必须通过提交 mutation,便于追踪。
Pinia :
更简洁的 API,完全支持 TypeScript,去除了 mutations,直接在 actions 中修改 state。
每个 store 独立定义,模块化自然。
对比 :Pinia 已成为 Vue 官方推荐,替代 Vuex。
// stores/counter.jsimport{ defineStore }from'pinia';exportconst useCounterStore =defineStore('counter',{state:()=>({count:0}),getters:{double:(state)=> state.count *2},actions:{increment(){this.count++;}}});// 组件中使用<script setup > import { useCounterStore }from './stores/counter' ;const counter =useCounterStore ();</script > <template > <p > {{ counter.count }}*2={{ counter.double }}</p > <button @click ="counter.increment" > 增加</button > </template >
4.5 路由原理 讲解 :前端路由根据 URL 变化渲染不同组件,无需刷新页面。Vue 官方路由库是 Vue Router。
Hash 模式 :利用 window.location.hash 和 hashchange 事件。
History 模式 :利用 HTML5 History API(pushState、replaceState),监听 popstate 事件。需要服务端配合避免 404。
Vue Router 核心 :
定义路由映射表。
<router-view> 显示匹配的组件。
<router-link> 导航链接。
动态路由、嵌套路由、导航守卫等。
// router/index.jsimport{ createRouter, createWebHistory }from 'vue-router' ;import Home from '../views/Home.vue' ;import About from '../views/About.vue' ;const routes =[{path:'/' ,component: Home },{path:'/about' ,component: About }];const router =createRouter({history:createWebHistory(), routes });exportdefault router;// main.js 中使用 app.use(router);
4.6 服务端渲染(SSR) 讲解 :SSR 在服务器端渲染 HTML 字符串,发送到客户端,提升首屏加载速度和 SEO。Vue 官方 SSR 方案是 Vue + Vue Router + Vue Server Renderer,或使用 Nuxt 框架。
Nuxt.js :基于 Vue 的 SSR 框架,提供文件路由、自动代码分割、静态站点生成等。
原理 :服务器执行 Vue 组件,生成 HTML,客户端激活(hydration)使页面可交互。
优点 :SEO 友好、更快首屏内容。
缺点 :服务器负载增加、开发复杂度上升。
<template > <div > <h1 > {{ title }}</h1 > <p > 服务端渲染示例</p > </div > </template > <script setup > </script >
5. 工程化与工具
5.1 Webpack 原理与配置 讲解 :Webpack 是一个模块打包工具,将项目中的模块(JS、CSS、图片等)打包成静态资源。
核心概念 :
Entry :入口文件,依赖图起点。
Output :输出文件位置和名称。
Loader :处理非 JS 文件(如 CSS、图片),将其转换为模块。
Plugin :执行更广泛的任务(如压缩、提取 CSS、生成 HTML)。
Mode :development/production,内置优化。
常用 Loader :babel-loader(转译 ES6+)、css-loader(解析 CSS)、style-loader(注入 style 标签)、file-loader/url-loader(处理资源)。
常用 Plugin :HtmlWebpackPlugin(生成 HTML)、MiniCssExtractPlugin(提取 CSS)、DefinePlugin(定义环境变量)、TerserPlugin(压缩 JS)。
构建流程 :
初始化参数:从配置文件和 Shell 语句中读取合并参数。
开始编译:初始化 Compiler 对象,加载插件。
确定入口:根据 Entry 找到所有依赖模块。
编译模块:从入口开始,递归调用 Loader 转译模块。
完成模块编译:得到每个模块的最终内容和依赖关系。
输出资源:根据依赖关系组装 Chunk,生成文件列表。
写入文件系统。
案例 (webpack.config.js 简化):
const HtmlWebpackPlugin =require('html -webpack-plugin');const MiniCssExtractPlugin =require('mini-css-extract-plugin'); module.exports ={entry:'./src/index.js' ,output:{filename:'bundle.[contenthash].js' ,path: path.resolve (__dirname,'dist' )},module:{rules:[{test:/\.js$/,use:'babel-loader' },{test:/\.css$/,use:[MiniCssExtractPlugin.loader,'css-loader' ]}]},plugins:[newHtmlWebpackPlugin ({template:'./src/index.html' }),newMiniCssExtractPlugin({filename:'styles.[contenthash].css' })]};
5.2 Babel 原理 讲解 :Babel 是一个 JavaScript 编译器,将 ES6+ 代码转换为向后兼容的版本。
工作流程 :
解析(Parse) :将源码解析为抽象语法树(AST)。
转换(Transform) :遍历 AST,通过插件修改节点。
生成(Generate) :将修改后的 AST 生成目标代码。
预设(Presets) :一组插件的集合,如 @babel/preset-env 根据目标环境自动转换。
插件(Plugins) :单个转换功能,如 @babel/plugin-transform-arrow-functions。
module .exports ={presets:[['@babel/preset-env',{targets:'> 0.25%, not dead'}]] ,plugins:['@babel/plugin-proposal-optional-chaining' ]};
5.3 模块化
CommonJS (Node 环境):module.exports / exports 导出,require 导入。同步加载。
ES Module (ES6 标准):export / export default 导出,import 导入。静态分析,异步加载,支持 Tree Shaking。
AMD :require.js 实现,浏览器端异步加载。
UMD :兼容 CommonJS 和 AMD 的通用模块定义。
/ / ES Module 导出exportconst name = 'module' ;exportdefaultfunctionsayHi(){ console.log ('Hi' );}/ / 导入import sayHi,{ name }from './module.js' ;
5.4 Git 工作流 讲解 :Git 是分布式版本控制系统,团队协作需规范流程。
常用命令 :git clone、git add、git commit、git push/pull、git branch、git merge、git rebase。
分支策略 :
Git Flow:master(稳定)、develop(开发)、feature/*(功能)、release/*(发布)、hotfix/*(紧急修复)。
GitHub Flow:master 始终可部署,从 master 拉取功能分支,完成后提 PR 合并。
GitLab Flow:环境分支(pre-production、production)结合合并请求。
Merge 与 Rebase 区别 :merge 保留历史分支,rebase 使历史线性,但需注意公共分支不要 rebase。
# 创建功能分支git checkout -b feature/new-button # 开发后提交gitadd.git commit -m"add new button "# 合并到主分支git checkout main git merge feature/new-button
5.5 CI/CD 基础 讲解 :持续集成/持续部署自动化构建、测试、部署流程。
CI :开发频繁合并代码到主干,自动构建和测试,及早发现问题。
CD :通过 CI 验证后,自动部署到预发布或生产环境。
常见工具 :Jenkins、GitHub Actions、GitLab CI、Travis CI。
流程示例 :push 代码 → 触发 CI 运行测试 → 测试通过 → 构建镜像/打包 → 部署到服务器。
name: CI/CD on:[push]jobs :build:runs-on: ubuntu-latest steps:-uses: actions/checkout@v2 -run: npm install -run: npm test -run: npm run build -name: Deploy uses: peaceiris/actions-gh-pages@v3 with:github_token: ${{ secrets.GITHUB_TOKEN } }publish_dir: ./dist
6. 性能优化
6.1 加载优化
减少 HTTP 请求 :合并 CSS/JS 文件,使用雪碧图,内联小资源。
资源压缩 :Gzip/Brotli 压缩文本文件,压缩图片(WebP、压缩工具)。
使用 CDN :将静态资源分布到全球节点,加速用户访问。
懒加载 :图片、路由组件等按需加载,减少首屏资源。
预加载/预连接 :<link rel="preload"> 预加载关键资源,dns-prefetch、preconnect 提前解析 DNS 和建立连接。
<linkrel="preload"href="main.css"as="style"><linkrel="preconnect"href="https://api.example.com"><imgsrc="placeholder.jpg"data-src="real.jpg"loading="lazy"alt="...">
6.2 渲染优化
减少重排重绘 :参见 3.2 节。
避免内存泄漏 :及时解绑事件、清除定时器、销毁全局变量。
使用 will-change :提示浏览器准备优化某个元素的变化。
长列表优化 :虚拟列表(只渲染可视区域),如 vue-virtual-scroller。
Web Worker :将复杂计算放在后台线程,避免阻塞主线程。
// 使用 will-change.animated { will-change: transform, opacity;}// Vue 中使用虚拟列表(假设有大量数据)<template > <RecycleScroller :items ="list" :item-size ="50" key-field ="id" v-slot ="{ item }" > <div > {{ item.name }}</div > </RecycleScroller > </template >
6.3 打包优化
代码分割 :Webpack 的 splitChunks 提取公共依赖,路由懒加载。
Tree Shaking :移除未使用的代码,需 ES Module 支持。
按需加载 :第三方库如 Lodash 使用 lodash-es 或插件按需引入。
压缩代码 :TerserPlugin 压缩 JS,CssMinimizerPlugin 压缩 CSS。
图片优化 :压缩图片,使用 url-loader 将小图片转为 base64。
// Vue 路由懒加载const routes =[{path:'/about' ,component:()=>import('./views/About.vue' )}] ;// Webpack splitChunksoptimization:{splitChunks:{chunks:'all' ,cacheGroups:{vendor:{test:/[\\/]node_modules[\\/]/,name:'vendors' }}}}
6.4 性能指标
FP(First Paint) :首次绘制像素。
FCP(First Contentful Paint) :首次绘制任何内容(文本、图片)。
LCP(Largest Contentful Paint) :最大内容绘制时间,衡量主要内容加载速度。
FID(First Input Delay) :首次输入延迟,衡量交互响应性。
CLS(Cumulative Layout Shift) :累计布局偏移,衡量视觉稳定性。
TTI(Time to Interactive) :可交互时间。
工具 :Lighthouse、Chrome DevTools Performance 面板。
// 使用 Performance API 测量 FCPnewPerformanceObserver((entryList)=>{for(const entry of entryList.getEntries()){ console.log('FCP:' , entry.startTime);}}).observe({type :'paint' ,buffered:true });
7. 数据结构与算法(前端常考)
7.1 常见数据结构
数组 :连续内存,查找 O(1),插入删除 O(n)。
链表 :非连续,插入删除 O(1),查找 O(n)。
栈 :后进先出(LIFO),如括号匹配。
队列 :先进先出(FIFO),如任务队列。
树 :二叉树、二叉搜索树、平衡树(红黑树)。
哈希表 :键值对,查找 O(1),处理冲突(链表法、开放寻址)。
// 栈应用:括号匹配functionisValid(s){const stack =[];const map ={'(' :')' ,'[' :']' ,'{' :'}' };for (let c of s){if (map [c]){ stack.push(c);}else {const top = stack.pop();if (map [top]!== c)returnfalse;}}return stack.length ===0 ;} console.log(isValid('()[]{}' ));// true
7.2 排序算法
冒泡排序 :O(n²),稳定。
快速排序 :O(n log n) 平均,不稳定,分治思想。
归并排序 :O(n log n),稳定,分治+合并。
选择排序 :O(n²),不稳定。
插入排序 :O(n²),稳定,适合小规模数据。
// 快速排序functionquickSort(arr){if(arr.length <=1 )return arr;const pivot = arr[0] ;const left =[] , right =[] ;for(let i =1 ; i < arr.length ; i ++){ arr[i] < pivot ? left .push (arr[i] ): right.push (arr[i]);}return[...quickSort(left), pivot,...quickSort(right)] ;} console.log (quickSort([3,6,8,10,1,2,1] ));// [1,1,2,3,6,8,10]
7.3 递归与迭代 讲解 :递归函数调用自身,需有终止条件;迭代通过循环实现。
递归缺点 :可能导致栈溢出,性能较低(可优化为尾递归)。
适用场景 :树的遍历、分治算法。
示例 :斐波那契数列、汉诺塔。
// 递归求斐波那契(有大量重复计算,可优化)functionfib(n){if(n <=1 )return n;returnfib(n-1 )+fib(n-2 );}// 迭代优化functionfibIter(n){let a =0 , b =1 ;for(let i =2 ; i <= n; i ++){[a, b] =[b, a + b] ;}return n ===0 ? a : b;}
7.4 常见算法题
数组去重 :利用 Set、filter + indexOf、reduce。
数组扁平化 :递归、flat(Infinity)、reduce + concat。
函数柯里化 :将多参数函数转换为一系列单参数函数。
节流/防抖 :见 2.8。
深拷贝 :见 2.7。
手写 Promise :考察对异步的理解。
查找最长无重复子串 :滑动窗口。
// 数组扁平化functionflatten(arr){return arr.reduce ((acc, val)=> Array.isArray (val)? acc.concat (flatten(val)): acc.concat (val),[]);} console.log (flatten([1,[2,[3,4] ,5 ]]));// [1,2,3,4,5] // 函数柯里化functioncurry(fn){returnfunctioncurried(...args ){if(args.length >= fn.length ){returnfn.apply (this, args);}else{return(...args2 )=>curried.apply (this, args.concat (args2));}};}constadd=(a ,b ,c)=> a +b +c;const curriedAdd =curry(add); console.log (curriedAdd(1 )(2 )(3 ));// 6
8. 设计模式与架构
8.1 常见设计模式
单例模式 :确保一个类只有一个实例,如全局状态管理(Pinia store)。
观察者模式 :主题维护观察者列表,状态变化时通知所有观察者(如 Vue 的响应式系统)。
发布订阅模式 :类似观察者,但通过事件中心解耦,如 EventBus。
工厂模式 :创建对象而不指定具体类,如 Vue 的 createApp。
策略模式 :定义一系列算法,封装起来可互换,如表单验证策略。
代理模式 :为对象提供替代或占位符,控制访问,如虚拟代理(图片懒加载)。
classEventBus{constructor ( ){this .events ={};}on (event, listener ){(this .events [event]||(this .events [event]=[])).push (listener);}emit (event, data ){(this .events [event]||[]).forEach (listener =>listener (data));}off (event, listener ){if (!this .events [event])return ;this .events [event]=this .events [event].filter (l => l !== listener);}}const bus =newEventBus (); bus.on ('login' ,(user )=> console .log ('登录:' , user)); bus.emit ('login' ,{name :'Alice' });
8.2 MVC / MVVM 模式
MVC :Model(数据)、View(视图)、Controller(业务逻辑)。用户操作→Controller→更新Model→更新View。
MVVM :Model、View、ViewModel(数据绑定器)。通过双向绑定,View 变化自动更新 Model,反之亦然。如 Vue 的响应式系统。
案例 :Vue 是 MVVM 的典型实现,ViewModel 对应组件实例,Model 对应 data,View 对应模板。
9. 软技能与开放性题目
项目经验 :能清晰描述项目背景、技术选型、个人贡献、难点及解决方案。
团队协作 :沟通方式、代码审查、冲突解决。
学习能力 :关注新技术、阅读源码、参与社区。
开放性题目 :如'如果让你设计一个前端监控系统,你会怎么做?'可从数据采集(性能、错误、行为)、上报策略、数据可视化等方面展开。
案例 :回答前端监控系统设计时,可提及使用 Performance API 收集指标,通过 Beacon API 上报,利用错误事件监听 JS 错误,使用 Sentry 等工具。
总结 前端面试覆盖范围广、深度要求高。本文从基础到进阶,系统梳理了 HTML/CSS、JavaScript、浏览器网络、框架(以 Vue 为例)、工程化、性能优化、算法设计模式等核心知识点,并给出了深入解析及案例。希望你能结合这些内容,举一反三,在面试中不仅'知其然',更能'知其所以然',展现出作为一名高级前端开发工程师的技术底蕴和解决问题的能力。祝你面试顺利!
相关免费在线工具 curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online