哈喽,我是一个学前端的前端,又菜又爱玩,话说在前端八股文这个圈子,要说的话太多,不是一两句能说得清,今天带领白白一起进入,冲!冲!冲!话不多说,直接开炫~
🔥 HTML 部分
-
DOCTYPE是什么?它有什么用?
声明位于文档最顶部,用于告知浏览器使用哪种HTML版本来解析页面。它确保浏览器能正确地渲染页面,而不是进入怪异模式。 -
HTML5 有哪些语义化标签?你用它们来干什么?
有
<header>、<nav>、<main>、<article>、<section>、<aside>、<footer>等。我用它们来更清晰地描述页面结构,这样代码可读性更好,也利于SEO和无障碍访问。 -
<meta name="viewport">标签的作用是什么?把它写出来。它的作用是控制移动端视口的大小和缩放比例,让页面在移动设备上正确显示。
<meta name="viewport" content="width=device-width, initial-scale=1.0">
-
什么是
data-*属性?它有什么用?它是自定义属性,用于在HTML元素上存储额外的数据。可以通过JavaScript的 dataset 属性来获取和操作。例如,
<div data-id="123"></div>用来存储元素的ID。
-
<script>标签中async和defer属性有什么区别?它们都用于异步加载脚本,不阻塞HTML解析。
async:脚本下载完就立即执行,执行顺序不确定。defer:脚本会等到HTML解析完成后,DOMContentLoaded事件触发前按顺序执行。
🎨 CSS 部分
-
说说CSS的盒模型。
box-sizing: border-box;有什么作用?盒模型由内容、内边距、边框、外边距组成。标准盒模型的 width 只指内容宽度。box-sizing: border-box; 会让元素的 width 和 height 包含内容、内边距和边框,这使得布局计算更直观。
-
CSS选择器的权重优先级是怎样的?
!important > 内联样式 > ID选择器 > Class/属性/伪类选择器 > 标签/伪元素选择器 > 通配符。权重计算不进位。
-
写出至少三种让一个
div水平垂直居中的方法。
✅ 方法1:Flexbox(现代推荐)
特点:代码简洁,响应式友好
<div class="container">
<div class="centered-box">Hello, Centered!</div>
</div>
.container {
display: flex; /* 启用 Flex 布局 */
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
height: 100vh; /* 需要明确容器高度(示例用视口高度) */
}
.centered-box {
width: 200px;
background: lightblue;
}
✅ 方法2:绝对定位 + Transform(经典兼容方案)
特点:兼容性好,不依赖父级宽高
.container {
position: relative; /* 父级相对定位 */
height: 100vh;
}
.centered-box {
position: absolute; /* 子级绝对定位 */
top: 50%; /* 先定位到50%位置 */
left: 50%;
transform: translate(-50%, -50%); /* 反向位移自身宽高的50% */
width: 200px;
background: lightcoral;
}
✅ 方法3:Grid(单行代码版)
特点:CSS Grid 的最简写法
.container {
display: grid; /* 启用 Grid 布局 */
place-items: center; /* 一次性设置水平和垂直居中 */
height: 100vh;
}
.centered-box {
width: 200px;
background: lightgreen;
}
注: ⚡ place-items 是 align-items + justify-items 的缩写
-
position的属性值有哪些?absolute是相对于什么定位的?static, relative, absolute, fixed, sticky。absolute 是相对于最近一个非
static定位的祖先元素进行定位,如果没有,则相对于初始包含块。 -
请解释一下什么是BFC?它有什么用?
BFC是块级格式化上下文,是一个独立的渲染区域。创建BFC(如 overflow: hidden)可以清除浮动、防止外边距重叠、隔离外部元素。
⚡ JavaScript 核心部分
-
var,let,const的区别是什么?- var 有变量提升,无块级作用域。
- const 声明常量,必须初始化,不可重新赋值(但对象内容可修改)。
- let/const 有块级作用域,无变量提升,存在暂时性死区。
-
null和undefined有什么区别?undefined 表示变量已声明但未赋值。null 表示一个空的对象引用,是主动赋值的。
-
==和===有什么区别?== 会在比较前进行类型转换;=== 是严格相等,要求值和类型都相同。
-
说说基本数据类型和引用数据类型的区别。
基本数据类型(如Number, String)保存在栈内存中,按值访问。
引用数据类型(如Object, Array)地址在栈,值在堆,按引用访问。赋值时,基本类型是值拷贝,引用类型是地址拷贝。
-
谈谈你对作用域链的理解。
当访问一个变量时,会从当前作用域开始查找,如果找不到就向上级作用域查找,直到全局作用域,这个链式结构就是作用域链。
-
什么是闭包?闭包有什么用途?
闭包是能够访问其他函数内部变量的函数。
它有两个主要用途:
- 创建私有变量,避免全局污染。
- 让变量的值始终保持在内存中。
· 例子:
function createCounter() { let count = 0; return function() { return ++count; }; } const counter = createCounter(); // counter 就是一个闭包 console.log(counter()); // 1 -
setTimeout(() => { console.log(1) }, 0); console.log(2);请问打印顺序是什么?为什么?打印顺序是 2, 1。因为 setTimeout 是异步宏任务,即使延迟为0,也会等到同步任务(console.log(2))和当前的微任务都执行完后才执行。
-
Promise是什么?它解决了什么问题?
Promise是一种用于处理异步操作的对象。它解决了回调地狱的问题,让异步代码更易读、更易于维护。它有三种状态:pending, fulfilled, rejected。
-
说说
async/await的使用方式和优点。async 用于声明一个异步函数,await 用于等待一个Promise的解决。它让异步代码的写法看起来像同步代码,非常清晰,避免了复杂的 .then() 链式调用。
-
如何给一个按钮绑定点击事件?
有三种方式:
- HTML中:
<button onclick="handleClick()"> - JS中:
button.addEventListener('click', handleClick) - (不推荐)
button.onclick = handleClick
- HTML中:
-
什么是事件委托?为什么使用它?
事件委托是利用事件冒泡,将子元素的事件监听统一委托给父元素。
好处是:
- 减少内存消耗(只需要一个事件监听器)。
- 可以动态处理后来添加的子元素。
-
箭头函数和普通函数有什么区别?
最主要区别是
this的指向:- 箭头函数没有自己的 this,它继承自定义时所在的作用域。
- 普通函数的 this 指向调用它的对象。
-
如何用ES6的方法实现数组去重?
[...new Set([1, 2, 2, 3])] 或 Array.from(new Set([1, 2, 2, 3]))。
⚛️ Vue / React 框架部分
Vue:
-
Vue 的生命周期钩子函数你知道哪些?
created和mounted有什么区别?常用有 beforeCreate, created, beforeMount, mounted, beforeUpdate, updated, beforeUnmount, unmounted。
created:实例创建完成,数据观测已完成,但DOM还未生成。
mounted:DOM已挂载完成,可以操作DOM了。
-
v-if和v-show的区别是什么?v-if 是条件性地渲染元素,为false时元素不存在于DOM中。
v-show 只是通过CSS的 display 属性来控制显示/隐藏,元素始终在DOM中。频繁切换用
v-show,运行时条件很少改变用v-if。 -
Vue 组件之间如何通信?
- 父传子:通过 props。
- 子传父:子组件通过 $emit 触发事件,父组件监听该事件。
- 兄弟组件/跨级:可以使用Event Bus或Vuex/Pinia。
React:
-
React Hooks 你用过哪些?
useState和useEffect是做什么的?常用有 useState, useEffect, useContext。
- useState:用于在函数组件中添加状态。
- useEffect:用于在函数组件中执行副作用操作(如数据获取、订阅),可以模拟生命周期。
-
为什么不能直接修改State?应该怎么做?
直接修改State(如 this.state.count = 1)不会触发组件重新渲染。应该使用 setState()(类组件)或状态设置函数(函数组件,如 setCount)来返回一个新状态。
-
为什么循环渲染列表时需要
key?key 帮助React识别哪些元素被改变、添加或删除,从而高效地更新虚拟DOM。它应该是稳定、唯一的值,绝不能用数组索引。
🌐 网络 & 浏览器
-
从浏览器输入URL到页面展示,中间发生了什么?
- DNS解析;
- 建立TCP连接(三次握手);
- 发送HTTP请求;
- 服务器处理并返回HTTP响应;
- 浏览器解析渲染(构建DOM树、CSSOM树、合成渲染树、布局、绘制);
- 断开TCP连接。
-
HTTP的常见状态码你知道哪些?
- 200 OK:成功。
- 301 Moved Permanently:永久重定向。
- 304 Not Modified:资源未修改,使用缓存。
- 404 Not Found:未找到资源。
- 500 Internal Server Error:服务器内部错误。
-
什么是跨域?如何解决跨域问题?
跨域是由浏览器的同源策略引起的。
解决方案有:
- CORS:后端设置响应头,如 Access-Control-Allow-Origin。
- 代理服务器:在开发环境中,配置webpack-dev-server等工具进行代理。
-
浏览器本地存储方式有哪些?
cookie, localStorage, sessionStorage。
- cookie:大小约4KB,会随请求发送到服务器。
- localStorage:大小约5MB,持久存储,除非手动清除。
- sessionStorage:大小约5MB,仅在当前会话有效,标签页关闭即清除。
💻 编程题 & 场景题
-
手写一个函数,实现数组扁平化。
function flatten(arr) { return arr.reduce((prev, curr) => { return prev.concat(Array.isArray(curr) ? flatten(curr) : curr); }, []); } // 或直接用 ES2019 的 flat: arr.flat(Infinity) -
手写一个简单的深拷贝函数。
function deepClone(obj) { if (obj === null || typeof obj !== 'object') return obj; if (obj instanceof Date) return new Date(obj); if (obj instanceof Array) return obj.map(item => deepClone(item)); const cloned = {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { cloned[key] = deepClone(obj[key]); `}` } return cloned; } -
如果让你实现一个搜索框,在用户输入时自动提示,你会如何设计和优化?
我会使用 防抖。当用户连续输入时,不会每次按键都请求,而是设置一个延迟(如300ms),只有在用户停止输入超过这个延迟后,才发起请求获取提示数据。这样可以减少不必要的网络请求和服务器压力。
-
你用过Git吗?常用的Git命令有哪些?
用过。
- git clone [url] :克隆仓库。
- git add . :添加更改到暂存区。
- git commit -m "message" :提交更改。
- git push origin main :推送到远程仓库。
- git pull :拉取远程更新。
写在最后:
还请各位大佬不要喷,大家互帮互助,一起当牛马~