⚡Promise:异步的"承诺书"如何兑现?
js
const p = new Promise((resolve, reject) => {
setTimeout(() => {
Math.random() > 0.5 ? resolve("成功") : reject("失败");
}, 1000);
});
p.then(console.log).catch(console.error);
📌 Promise 有 3 个状态:
pending
:初始态,等待结果fulfilled
:成功态,被resolve
rejected
:失败态,被reject
状态单向流动 :pending → fulfilled
或 pending → rejected
,不可逆 ❗
⚠️ 状态一旦改变,永不回头?
「Q1: Promise 状态变了,then 还能监听到吗?」
A1: 能!即使 resolve 在 then 之前,Promise 会"记住"结果,后续 then 依然执行(微任务队列机制)👉继续看?💡
「Q2: 多个 then 是串行还是并行?如果前一个 throw 错误会怎样?」
A2: then 链是串行微任务,前一个 throw 会跳到最近的 catch(类似 try-catch)💥
「Q3: 手写一个最简 Promise,只实现 resolve、then 和状态机制?」
js
function MyPromise(executor) {
this.status = 'pending';
this.value = null;
this.onFulfilled = []; // 存储 then 回调
const resolve = (value) => {
if (this.status === 'pending') {
this.status = 'fulfilled';
this.value = value;
this.onFulfilled.forEach(fn => fn()); // 执行所有 then
}
};
executor(resolve, () => {}); // 简化 reject
}
MyPromise.prototype.then = function(onFulfilled) {
if (this.status === 'fulfilled') {
onFulfilled(this.value);
} else {
this.onFulfilled.push(() => onFulfilled(this.value)); // 缓存
}
};
🤯 你能补全异步 resolve 的微任务调度吗?(用 queueMicrotask)
「Q4: Promise.all 如果其中一个 reject,其他请求会取消吗?如何实现"失败不中断"?」
A4: 会!除非用 Promise.allSettled
或 .catch(() => null)
包装每个 Promise ✅
「Q5: Vue 的 nextTick 为什么用 Promise + MutationObserver 回退?说说事件循环优先级?」
A5: 因为 Promise 是微任务,比 setTimeout(宏任务)更快执行,保证 DOM 更新后立即回调 ⏱️
⚡闭包:函数的"私有保险箱"🧾
js
function outer() {
let count = 0;
return function inner() {
return ++count; // 引用了 outer 的变量
};
}
const counter = outer();
counter(); // 1
counter(); // 2
📌 闭包 = 函数 + 外层作用域的引用
即使外层函数执行完,变量仍被"封闭"保留。
⚠️ 闭包一定导致内存泄漏?🚫
「Q1: 闭包的变量什么时候释放?」
A1: 当 inner 函数被销毁(如全局引用被置 null),没有引用指向它时,GC 才回收。
「Q2: 为什么循环中用 var + setTimeout 会输出 5 个 5?闭包如何解决?」
js
for (var i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 0); // 全是5
}
// 闭包解法:
for (var i = 0; i < 5; i++) {
((i) => setTimeout(() => console.log(i), 0))(i);
}
👉用 let 呢?块级作用域自动形成闭包!
「Q3: React Hooks 为什么依赖闭包?useEffect 里用旧 state 是闭包问题吗?」
A3: 是!每次渲染生成新函数,闭包捕获当次 state。过期闭包是常见 bug 源头 ❗
「Q4: 如何在 Vue 3 setup 中避免闭包陷阱?」
A4: 用 ref
+ .value
或 toRefs
,确保引用最新响应式数据 💡
「Q5: 闭包能实现模块化吗?写一个防篡改的计数器模块?」
js
const Counter = (function() {
let count = 0;
return {
inc: () => ++count,
get: () => count
};
})();
面试官偷笑😏:这不就是 IIFE + 闭包的经典模式?
⚡ES6 新特性:不只是语法糖,是工程革命!
特性 | 作用 | 实战场景 |
---|---|---|
let/const |
块级作用域 | 避免 var 变量提升陷阱 |
arrow function |
无 this,更短语法 | 回调、map/filter |
destructuring |
解构赋值 | props、配置项提取 |
template string |
多行字符串 + 插值 | HTML 模板拼接 |
module (import/export) |
ES 模块化 | 前端工程基石 |
Promise |
异步编程 | 接口请求链 |
class |
语法糖 | Vue/React 组件 |
async/await |
同步写法 | 复杂流程控制 |
js
// 真实业务:用解构 + 默认值处理 API 响应
function renderUser({ name = '匿名', age, tags = [] } = {}) {
return `<div>${name}(${age}) - ${tags.join(',')}</div>`;
}
「Q1: class 是真正的类吗?和原型继承什么关系?」
A1: 不是!只是语法糖,本质仍是 prototype。class A {}
等价于 function A() {}
❗
「Q2: import 是静态的吗?动态导入怎么用?」
A2: 是!必须在顶层。动态用 import('./module.js')
返回 Promise 💡
「Q3: 为什么 ES6 模块是单例的?和 CommonJS 区别?」
A3: 因为模块实例只加载一次,导出的是"绑定"而非值拷贝。修改 export 会影响所有导入者 🤯
「Q4: 装饰器(Decorator)是 ES6 吗?现在用在哪儿?」
A4: 不是 ES6,是提案。但广泛用于 TypeScript + NestJS、MobX 等框架 👉继续看?
「Q5: 你项目中哪个 ES6 特性提升了可维护性?举个例子?」
A5: 解构 + 默认值让函数参数更清晰,减少 if 判断,代码自文档化 ✅
⚡SEO:不只是 meta 标签,是"搜索引擎恋爱学"💘
html
<head>
<title>精准关键词 - 品牌名</title>
<meta name="description" content="150字内吸引点击的摘要">
<meta name="robots" content="index,follow">
<link rel="canonical" href="https://example.com/page">
<meta property="og:title" content="社交分享标题">
</head>
📌 核心策略:
- 语义化 HTML(
<header>
,<article>
) - SSR / 预渲染(Vue/React 用 Nuxt/Next)
- 图片懒加载 +
alt
属性 - 结构化数据(JSON-LD)
- 移动友好 + 快速加载(Core Web Vitals)
「Q1: 客户端渲染(CSR)为什么不利于 SEO?」
A1: 爬虫可能拿不到动态内容,首屏 HTML 空白 ❌
「Q2: SSR 和 SSG 有什么区别?你项目用哪种?」
A2: SSR 每次请求生成 HTML,SSG 构建时生成。静态页用 SSG(如博客),动态用 SSR(如电商)✅
「Q3: 如何检测页面是否被正确索引?」
A3: Google Search Console 查"覆盖率",或 site:yourdomain.com
搜索 🔍
「Q4: meta keywords 还有用吗?」
A4: 没用!搜索引擎早已忽略,专注内容和外链 💥
「Q5: 你做过 SEO 优化,数据提升多少?」
A5: 某项目从 SSR 改造后,首屏可交互时间 ↓60%,收录率 ↑90% 📈
⚡HTTP 状态码:服务器的"情绪报告"📊
状态码 | 含义 | 场景 |
---|---|---|
200 |
OK | 请求成功 |
301 |
永久重定向 | 域名迁移 |
302 |
临时重定向 | A/B 测试 |
403 |
禁止访问 | 权限不足 |
404 |
未找到 | 页面删除 |
500 |
服务器错误 | 后端异常 |
「Q1: 301 和 302 对 SEO 有什么影响?」
A1: 301 会传递权重,302 不会。误用 302 可能导致 SEO 损失 ❗
「Q2: 403 和 401 有什么区别?」
A2: 401 是"未认证"(无 token),403 是"认证了但没权限"🔐
「Q3: 502、503、504 分别代表什么?」
A3: 502 Bad Gateway(网关错误),503 Service Unavailable(服务挂了),504 Gateway Timeout(超时)💥
「Q4: 如何优雅处理 404?前端路由怎么做?」
A4: Vue Router/React Router 配置 *
路由,显示自定义 404 页面 ✅
「Q5: 状态码是 HTTP/1.1 的吗?HTTP/2 有变化吗?」
A5: 状态码语义不变,但 HTTP/2 用二进制帧传输,效率更高 🚀
⚡缓存头:浏览器的"记忆宫殿"🏰
请求头 | 作用 |
---|---|
Cache-Control |
缓存策略(如 max-age=3600 ) |
Expires |
过期时间(HTTP/1.0) |
ETag |
资源指纹,协商缓存 |
If-None-Match |
携带 ETag 询问是否变更 |
Last-Modified |
最后修改时间 |
If-Modified-Since |
携带时间询问 |
http
Cache-Control: public, max-age=31536000, immutable
👉 静态资源用强缓存 + 哈希文件名
「Q1: 强缓存和协商缓存有什么区别?」
A1: 强缓存不发请求(200 from memory/disk cache),协商缓存发请求问服务器(304 Not Modified)✅
「Q2: ETag 和 Last-Modified 哪个优先级高?」
A2: ETag 更精确(内容指纹),优先级更高 💡
「Q3: 如何让 CDN 缓存失效?」
A3: 改文件名(hash)、发 purge 请求、设置短 TTL ❗
「Q4: Cache-Control: no-cache 是不缓存吗?」
A4: 错!是"使用前必须验证",实际会缓存,但每次发请求问服务器 🤯
「Q5: 你项目中如何配置缓存策略?」
A5: HTML:no-cache;JS/CSS:max-age一年 + hash;API:根据业务设短缓存 ✅
⚡HTTPS:加密的"安全隧道"🔐
⚠️ 证书如何验证?
「Q1: HTTPS 为什么安全?解决了什么问题?」
A1: 防窃听(加密)、防篡改(完整性)、防冒充(身份认证)✅
「Q2: SSL/TLS 握手过程中,对称加密和非对称加密怎么配合?」
A2: 非对称加密(如 RSA)传"预主密钥",后续用对称加密(如 AES)通信,兼顾安全与性能 💡
「Q3: 什么是中间人攻击?HTTPS 如何防范?」
A3: 攻击者伪造证书。HTTPS 依赖 CA 机构签名,浏览器验证证书链合法性 ❗
「Q4: 证书过期了会怎样?如何自动续签?」
A4: 浏览器警告。用 Let's Encrypt + certbot 自动续签 👉继续看?
「Q5: HTTP/2 必须用 HTTPS 吗?」
A5: 不是必须,但主流浏览器只支持 HTTPS 的 HTTP/2 🚀