前端面试突击重点 (1小时冲刺)
1. 响应式布局 (Responsive Design)
核心概念:一套代码适应不同屏幕尺寸。
- 媒体查询 (
@media): CSS3 核心技术,根据视口宽度应用不同样式。css@media (max-width: 768px) { .container { flex-direction: column; } } - Flexbox (弹性盒子): 一维布局模型,适合对齐和分配空间。
justify-content: 主轴对齐 (center, space-between)align-items: 交叉轴对齐 (center, stretch)
- Grid (网格布局): 二维布局模型,适合复杂页面结构。
- 相对单位:
rem: 相对于根元素 (html) 的字体大小。em: 相对于父元素的字体大小。vw/vh: 相对于视口宽度/高度的 1%。
- 移动端适配: 设置
<meta name="viewport" content="width=device-width, initial-scale=1.0">。
2. 闭包 (Closure)
回答 闭包 时,一定要提到“私有变量”和“内存泄漏”。
定义:函数能够访问其词法作用域,即使该函数在当前作用域之外执行。简单说就是 函数 + 函数内部能访问的变量。
通俗理解: 当一个内部函数引用了外部函数的变量,并且这个内部函数被返回或传递到外部执行时,就形成了闭包。即使外部函数已经执行结束,内部函数依然“记得”并能访问外部函数作用域中的变量。
核心作用:
- 数据私有化:创建私有变量,外部无法直接修改。
- 保持状态:让变量的值始终保存在内存中。
代码示例:
javascript
function createCounter() {
let count = 0; // 私有变量
return function () {
count++;
return count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2注意事项:滥用闭包可能导致内存泄漏(变量无法被垃圾回收)。
3. 节流 (Throttle) 与 防抖 (Debounce)
目的:优化高频事件(如 resize, scroll, input),减少性能消耗。
防抖 (Debounce)
- 原理:事件触发后等待 n 秒执行;如果在 n 秒内再次触发,则重新计时。
- 场景:搜索框联想输入(输完再发请求)、窗口大小调整。
- 口诀:“回城读条,被打断就重来”。
节流 (Throttle)
- 原理:规定单位时间内,只能触发一次函数。
- 场景:滚动加载(scroll)、按钮防止重复点击。
- 口诀:“技能冷却,CD 没好点也没用”。
js
function debounce(fn, delay) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
// 节流
function throttle(fn, delay) {
let timer = null;
return function (...arg) {
if (timer) return;
fn.apply(this, arg);
timer = setTimeout(() => {
timer = null;
}, delay);
};
}4. Promise 状态
Promise 是异步编程的解决方案。
三种状态:
- Pending (进行中):初始状态。
- Fulfilled (已成功):操作成功,调用
resolve。 - Rejected (已失败):操作失败,调用
reject。
特点:
- 状态不受外界影响。
- 状态一旦改变(Pending -> Fulfilled 或 Pending -> Rejected),就不会再变。
js
static all(promises) {
const promisesArr = Array.from(promises);
const len = promisesArr.length;
if (!len) return MyPromise.resolve([]);
return new MyPromise((resolve, reject) => {
const values = [];
let count = len;
promisesArr.forEach((promise, index) => {
promise.then(val => {
values[index] = val;
if (--count === 0) resolve(values);
}, reject);
});
});
}5. 箭头函数 vs 普通函数
| 特性 | 箭头函数 (() => {}) | 普通函数 (function() {}) |
|---|---|---|
| this 指向 | 没有自己的 this,捕获定义时上下文的 this。 | 取决于调用方式(谁调用指向谁)。 |
| 构造函数 | 不能作为构造函数,不能使用 new。 | 可以作为构造函数。 |
| arguments | 没有 arguments 对象,使用剩余参数 ...args。 | 有 arguments 对象。 |
| 原型 | 没有 prototype 属性。 | 有 prototype 属性。 |
适用场景:箭头函数适合回调函数、需要保留外层 this 的场景;普通函数适合对象方法、构造函数。
6. ES6 对象新增方法
- 属性简写:
{ x, y }等同于{ x: x, y: y }。 - 方法简写:
{ hello() { ... } }。 Object.assign(target, ...sources):合并对象(浅拷贝)。Object.keys(obj): 返回键名数组。Object.values(obj): 返回键值数组。Object.entries(obj): 返回键值对数组[[key, val], ...]。Object.is(value1, value2): 比较两个值是否严格相等(修复了===中NaN不等于NaN的问题)。
7. 对象合并方法
Object.assign({}, obj1, obj2)- 浅拷贝。
- 后合并的属性覆盖前面的。
扩展运算符 (
...)const newObj = { ...obj1, ...obj2 }- 浅拷贝,语法更简洁。
深拷贝 (Deep Clone)
- 简易版:
JSON.parse(JSON.stringify(obj))- 缺点:无法处理函数、undefined、Symbol、循环引用。
- 手写递归:判断类型,递归复制。
- 库函数:
lodash.cloneDeep(obj)。
- 简易版:
8. 组件通信 (以 Vue 为例)
回答 组件通信 时,区分“父子”、“跨层级”和“全局”三种场景来列举。
- 父传子:
props - 子传父:
$emit(发布订阅模式) - 兄弟组件:
- EventBus (Vue 2 常用,Vue 3 推荐 mitt)。
- 状态管理: Vuex / Pinia (最推荐)。
- 状态提升: 将状态提升到共同父组件。
- 跨层级 (祖孙):
provide/inject(依赖注入)。$attrs/$listeners。
- 访问实例:
ref(获取组件实例或 DOM)。$parent/$children。
