前端面经速记

前端面经速记

一、JavaScript 基础

数组方法

  • 增:push/pop(尾)、unshift/shift(头)、splice(任意位置)
  • 删:spliceslice(返回新数组)、filter
  • 改:splicefill
  • 查:indexOffindfindIndexincludes
  • 遍历:forEach(无返回)、map(返回新数组)、filterreducesomeevery
  • 其他:concatjoinreversesortflat

数组深拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 方法1:JSON(不能拷贝函数、undefined、循环引用)
JSON.parse(JSON.stringify(arr))

// 方法2:结构化克隆(推荐)
structuredClone(arr)

// 方法3:递归实现
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') return obj;
const clone = Array.isArray(obj) ? [] : {};
for (let key in obj) {
clone[key] = deepClone(obj[key]);
}
return clone;
}

forEach vs map

forEach map
返回值 undefined 新数组
用途 纯遍历/副作用 数据转换
链式调用
性能 略快 略慢

find

  • 作用:返回第一个符合条件的元素
  • 无匹配:返回 undefined
  • 对比:findIndex 返回索引,无匹配返回 -1

二、Vue2 核心

组件通信方式

  1. 父子props / $emit
  2. 父→子ref / $children / $parent
  3. 兄弟/跨级EventBus$on/$emit
  4. 全局Vuex / provide/inject
  5. v-model.sync 修饰符

computed vs watch

computed watch
性质 计算属性(缓存) 监听器
用途 派生数据 响应数据变化执行逻辑
依赖 自动追踪 手动声明
异步
立即执行 immediate: true

子组件调父组件属性

1
2
3
4
5
// 方法1:$parent(不推荐,耦合高)
this.$parent.xxx

// 方法2:props + $emit(推荐)
// 方法3:provide/inject(跨级)

Vue2 指令

  • v-bind(:):绑定属性
  • v-on(@):绑定事件
  • v-model:双向绑定
  • v-if/v-else/v-show:条件渲染
  • v-for:列表渲染(key必加)
  • v-html:渲染HTML(XSS风险)
  • v-text:文本插值
  • v-pre:跳过编译
  • v-once:只渲染一次
  • v-cloak:解决闪烁

v-if vs v-show

v-if v-show
原理 条件渲染(DOM增删) CSS切换 display:none
切换开销
初始渲染 条件为false时不渲染 始终渲染
适用场景 很少切换 频繁切换

data 为什么是函数不是对象

1
2
3
4
5
// 对象:所有实例共享同一引用,数据互相影响 ❌
// 函数:每次返回新对象,实例数据独立 ✅
data() {
return { count: 0 }
}

三、Vue Router

路由传参方式

  1. params/user/:idthis.$route.params.id
  2. query/user?id=1this.$route.query.id
  3. propsprops: true 解耦

params vs query

params query
URL /user/1 /user?id=1
刷新丢失 ✅(需配动态路由)
可见性 较隐蔽 明文

四、异步处理

三组件请求都完成再执行

1
2
3
4
5
6
7
8
9
// Promise.all
Promise.all([req1(), req2(), req3()]).then(([r1, r2, r3]) => {
// 全部完成
});

// async/await
async function fetchAll() {
const [r1, r2, r3] = await Promise.all([req1(), req2(), req3()]);
}

Promise vs async/await

  • Promise:链式调用,处理并发用 Promise.all/race
  • async/await:同步写法,可读性更好,本质还是Promise

五、浏览器存储

sessionStorage vs localStorage

sessionStorage localStorage
生命周期 页面关闭清除 永久(手动清除)
作用域 同源同标签页 同源所有标签页
容量 ~5MB ~5-10MB
刷新后 保留 保留

刷新后清除的存储

  • 需求:页面刷新后数据清除
  • 方案:sessionStorage
  • 注意:关闭标签页/浏览器才清除,刷新保留
  • 特殊:要刷新也清除 → 用 beforeunload 手动清空

六、性能优化

防抖 vs 节流(表单提交防重复点击)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 防抖:停止操作后执行(搜索框)
function debounce(fn, delay) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}

// 节流:固定间隔执行(按钮点击)
function throttle(fn, delay) {
let last = 0;
return (...args) => {
const now = Date.now();
if (now - last > delay) {
last = now;
fn(...args);
}
};
}

// 表单提交用:loading状态 / 节流 / 防抖