2026前端面试题及答案
2026前端面试题及答案
HTML/CSS 部分
1. 什么是盒模型?标准盒模型和IE盒模型的区别是什么?
答案: 盒模型是CSS中用于布局的基本概念,每个元素都被表示为一个矩形盒子,由内容(content)、内边距(padding)、边框(border)和外边距(margin)组成。
区别:
-
标准盒模型(W3C盒子模型):
width和height只包含内容(content) -
IE盒模型(怪异模式盒子模型):
width和height包含内容(content)、内边距(padding)和边框(border)
可以通过box-sizing属性切换:
/* 标准盒模型 */
box-sizing: content-box;
/* IE盒模型 */
box-sizing: border-box;
2. CSS选择器优先级如何计算?
答案: CSS选择器优先级从高到低:
!important- 内联样式(style="")
- ID选择器(#id)
- 类选择器(.class)、属性选择器([type="text"])、伪类(:hover)
- 元素选择器(div)、伪元素(::before)
- 通配符(*)、关系选择器(>, +, ~)
计算规则:
- ID选择器:100
- 类/属性/伪类:10
- 元素/伪元素:1
- 相加比较,值大的优先级高
3. BFC是什么?如何创建BFC?
答案: BFC(Block Formatting Context)块级格式化上下文,是Web页面的可视化CSS渲染的一部分,是一个独立的渲染区域。
创建BFC的方法:
-
float不为none -
position为absolute或fixed -
display为inline-block、table-cell、table-caption、flex、inline-flex -
overflow不为visible
BFC特性:
- 内部盒子垂直排列
- margin会重叠在同一个BFC中
- BFC区域不会与float box重叠
- BFC是独立容器,外部不影响内部
JavaScript部分
4. JavaScript中的事件循环机制是怎样的?
答案: JavaScript是单线程语言,通过事件循环机制实现异步。事件循环由以下部分组成:
- 调用栈(Call Stack):执行同步代码的地方
-
任务队列(Task Queue):
- 宏任务(macrotask):script整体代码、setTimeout、setInterval、I/O、UI渲染等
- 微任务(microtask):Promise.then/catch/finally、MutationObserver等
执行顺序:
- 执行同步代码(宏任务)
- 执行过程中遇到异步任务:
- 微任务放入微任务队列
- 宏任务放入宏任务队列
- 同步代码执行完毕,检查微任务队列并全部执行
- UI渲染(如果需要)
- 取出一个宏任务执行,重复上述过程
5. ES6中let/const与var的区别?
答案:
| var | let | const | |
|---|---|---|---|
| 作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
| 变量提升 | 有 | 暂时性死区 | 暂时性死区 |
| 重复声明 | 允许 | 不允许 | 不允许 |
| 全局属性 | 会成为 | 不会成为 | 不会成为 |
| 初始值 | 可不设 | 可不设 | 必须设置 |
| 修改值 | 可以 | 可以 | 不可以 |
6. Promise的原理是什么?手写一个简单的Promise实现。
答案: Promise是一种异步编程解决方案,主要解决回调地狱问题。它有三种状态:pending、fulfilled、rejected。
简单实现:
class MyPromise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn());
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
then(onFulfilled, onRejected) {
if (this.state === 'fulfilled') {
onFulfilled(this.value);
}
if (this.state === 'rejected') {
onRejected(this.reason);
}
if (this.state === 'pending') {
this.onFulfilledCallbacks.push(() => onFulfilled(this.value));
this.onRejectedCallbacks.push(() => onRejected(this.reason));
}
}
}
React/Vue框架部分
7.React中setState是同步还是异步的?
答案: 在React中,setState的行为表现有时"异步",有时"同步":
1.大部分情况下表现为异步(批量更新优化):
- React合成事件处理函数中(setTimeout/setInterval/Promise回调等原生事件外)
- React生命周期函数中
在这些情况下React会将多个setState合并为一个更新以提高性能。
2.某些情况下表现为同步:
- setTimeout/setInterval回调中
- DOM原生事件处理函数中
- Promise.then等异步代码中
React18后所有情况都默认批量处理(auto batching),如需强制同步可使用flushSync。
原理原因: React通过isBatchingUpdates标志控制是否批量更新,合成事件和生命周期会开启此标志。
###8.Vue的响应式原理是怎样的?
答案: Vue2.x使用Object.defineProperty,Vue3使用Proxy实现响应式:
Vue2实现原理: 1.数据劫持:通过Object.defineProperty对data对象每个属性添加getter/setter追踪变化。
Object.defineProperty(obj, key, {
get() { //依赖收集 },
set(newVal) { //触发更新 }
})
2.依赖收集:在getter中将观察者Watcher实例添加到Dep订阅器中。 3.派发更新:setter被触发时通知Dep中的所有Watcher重新计算并更新视图。 缺点:无法检测对象属性的添加删除,数组变动需特殊处理。
Vue3使用Proxy改进:
new Proxy(data, {
get(target, key){},
set(target, key, value){},
deleteProperty(target, key){}
})
优势:可直接监听对象/数组的各种变化;无需递归遍历整个对象初始化。
##性能优化相关
###9.Webpack有哪些常见的性能优化手段?
构建速度优化:
1.缩小文件搜索范围
resolve:{ modules:[path.resolve(__dirname,'node_modules')] },
module:{ noParse:/jquery|lodash/ } //忽略未模块化库的解析
2.缓存loader结果(cache-loader/babel-loader?cacheDirectory=true)
3.多进程构建(thread-loader/happyPack)
4.DllPlugin预编译不变模块
5.合理使用sourceMap(开发环境cheap-module-eval-source-map)
打包体积优化:
1.Tree Shaking(ES6模块+production模式+sideEffects配置)
2.Code Splitting:
optimization:{ splitChunks:{ chunks:'all' } },
entry:{ main:'./src/main.js', vendor:['lodash'] }
3.Scope Hoisting(ModuleConcatenationPlugin)
4.UglifyJsPlugin压缩混淆代码
5.Gzip压缩(compression-webpack-plugin)
6.CDN引入外部资源(externals)
7.PurgeCSS移除无用CSS
8.OptimizeCSSAssetsPlugin压缩CSS
9.ImageMinimizerPlugin压缩图片
10.babel按需加载polyfill
##算法与编程题
###10.[编程题]手写防抖和节流函数
防抖(debounce):高频触发时只在停止触发后执行一次
function debounce(fn, delay){
let timer=null;
return function(...args){
clearTimeout(timer);
timer=setTimeout(()=>fn.apply(this,args),delay);
}
}
节流(throttle):高频触发时每隔一段时间执行一次
function throttle(fn, interval){
let lastTime=0;
return function(...args){
const now=Date.now();
if(now-lastTime>=interval){
fn.apply(this,args);
lastTime=now;
}
}
}
//定时器版本节流:
function throttle(fn,delay){
let timer=null;
return function(...args){
if(!timer){
timer=setTimeout(()=>{
fn.apply(this,args);
timer=null;
},delay);
}
};
}
##HTTP与浏览器相关
###11.HTTPS的工作原理是什么?
HTTPS=HTTP+TLS/SSL加密层工作流程:
1.Client发送支持的加密算法列表+随机数A给Server
2.Server选择加密算法+发送数字证书+随机数B给Client
3.Client验证证书有效性(颁发机构/过期时间/域名匹配),生成随机数C并用证书公钥加密发送给Server
4.Server用私钥解密获取随机数C
5.Client和Server都用ABC三个随机数生成对称加密密钥(session key)
6.HTTP通信开始使用该密钥加密数据
关键点:
-CA机构验证服务器身份防止中间人攻击
-非对称加密交换对称密钥提高安全性又保证性能
-TLS握手阶段采用非对称加密通信阶段采用对称加密
安全特性: 机密性(对称加密)+完整性(MAC校验)+身份认证(X509证书链)