--- tags: [] create time: 2026-04-30 15:30 --- # 前端摸底测试(第六次)— 错题精讲 ## 概述 本次测试涵盖 **Axios、AJAX/XHR、JavaScript 核心、DOM/BOM、事件系统、CSS、浏览器存储与定时器、Node.js、Vue 3、React Hooks、Webpack、ESM 模块系统**等前端核心技术点。共 110 道单选题,本篇聚焦 37 道错题,按知识点分类逐一拆解错误原因并给出正确理解。 > [!tip] 使用建议 > 先通读各专题的"为什么错 → 为什么对"分析,再做右侧表格的自测检查,最后用「高频考点速览」串记薄弱概念。 --- ## 一、请求层:Axios & AJAX / XHR ### Q03:跨域方案辨析 | 项目 | 内容 | | ------ | ------------ | | ❌ 你的答案 | B(服务器 cors) | | ✅ 正确答案 | D(axios) | --- ### Q04:XHR 终止方法 > [!note] 纠正说明 > 此题你答对了。**`xhr.abort()`** 是唯一标准方法来中止一个正在进行的 XHR 请求。 ### Q18:readyState = 3 的含义 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | C(已应答) | | ✅ 正确答案 | B(交互中) | ```js // XHR readyState 五阶段 const STATE = { UNSENT: 0, // 未初始化 OPENED: 1, // open() 已调用 HEADERS_RECEIVED: 2, // 收到响应头 LOADING: 3, // ↓ 正在下载响应体(交互中) DONE: 4 // 完成 }; ``` > [!question] 💡 思考 > 为什么 `LOADING(3)` 适合做"流式进度展示"而不是 `DONE(4)`? ### Q38:AJAX 成功事件 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | B(onreadystatechange) | | ✅ 正确答案 | A(onload) | ```js // 推荐方式:onload — 简洁明了 xhr.onload = function () { if (xhr.status === 200) { console.log(xhr.responseText); } }; // 旧方式:onreadystatechange — 需要自行判断状态 xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { /*...*/ } }; ``` > [!important] 记忆要点 > - **`onload`**:请求完整结束(等同于 readyState===4),仅区分成功/失败 > - **`onerror`**:网络级别失败(DNS 错误、断网等) > - **`onreadystatechange`**:状态每变化一次都触发,需手动检查 `readyState === 4` ### Q39:CORS 响应头 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | D(Cross-Origin-Resource-Policy) | | ✅ 正确答案 | A(Access-Control-Allow-Origin) | > [!warning] 避坑 > 这是**服务端返回**的响应头,格式为 `Access-Control-Allow-Origin: https://example.com`。客户端不需要手动设置这个头部。 ### Q40:解析 JSON 响应的 API | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | B(XML.parse()) | | ✅ 正确答案 | A(JSON.parse()) | > [!abstract] 冷知识 > XHR 原生支持 `responseType = 'json'`,此时 `xhr.response` 直接就是解析好的 JS 对象,无需手动 `JSON.parse()`。 --- ## 二、HTTP 协议基础 ### Q51:HTTP 400 状态码 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | A(请求方式错误) | | ✅ 正确答案 | D(请求参数错误) | > [!memory] HTTP 状态码速记表 > > ```mermaid > graph LR > A["2xx 成功"] --> A1["200 OK"] > A --> A2["201 Created"] > B["3xx 重定向"] --> B1["304 Not Modified"] > C["4xx 客户端错误"] --> C1["400 Bad Request"] > C --> C2["401 Unauthorized"] > C --> C3["403 Forbidden"] > C --> C4["404 Not Found"] > D["5xx 服务端错误"] --> D1["500 Internal Server Error"] > D --> D2["502 Bad Gateway"] > ``` ### Q52:Content-Type 的作用 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | D(响应的资源类型) | | ✅ 正确答案 | A(请求体的类型) | > [!example] 常见 Content-Type > - `application/json` — JSON 数据(最常用) > - `application/x-www-form-urlencoded` — 传统表单 > - `multipart/form-data` — 文件上传 > - `text/html` / `text/css` / `image/png` — 响应端 --- ## 三、JavaScript 核心概念 ### Q07:JS 数据类型辨析 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | A(RegExp) | | ✅ 正确答案 | D(String) | > [!question] 💡 思考 > 为什么 RegExp / Function / Array 属于引用类型(对象),而 String 是基本类型? ```js typeof /pattern/ // "object" → RegExp 是对象类型 typeof function(){} // "function" → Function 是对象类型 typeof [] // "object" → Array 是对象类型 typeof "hello" // "string" → 基本类型! typeof new String("a") // "object" → String 包装对象才是对象类型 ``` ### Q06:值传递 vs 引用传递 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | A(10) | | ✅ 正确答案 | A(9) | ```js let num = 9; function fn(num) { num = num + 1; // 修改的是函数局部参数,不影响外层 } fn(num); console.log(num); // 9 —— 基本类型按值传递 ``` > [!example] 对比:引用类型的行为(Q14) > ```js > let arr = [1]; > function fn(arr) { > arr.push(3); // 修改的是同一块堆内存 > } > fn(arr); > console.log(arr); // [1, 3] > ``` ### Q23:一元加号 + 的类型转换 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | D(string) | | ✅ 正确答案 | B(number) | ```js typeof +'136'; // "number" // 等价于:Number('136') → 136 // '+' 作为一元运算符时,会将操作数转换为数字 ``` ### Q13 & Q43 & Q44:事件循环(Event Loop)输出顺序 这三道题都在考同一个核心:**同步 → Promise微任务 → setTimeout宏任务**。 | 题目 | ❌ 你的答案 | ✅ 正确答案 | |------|------------|-------------| | Q13 | D | C(2→3→5→4→1) | | Q43 | D | A(8,9,5,5,5,5,5) | | Q44 | D | A(23541) | 以 Q13 为例,执行过程分解: > [!abstract] Event Loop 执行流程 > > ```mermaid > flowchart TD > A["同步代码开始执行"] --> B["setTimeout 注册宏任务"] > B --> C["Promise 立即执行"] > C --> D["for 循环 resolve"] > D --> E["console.log 5"] > E --> F["同步代码结束"] > F --> G["微任务 then"] > G --> H["宏任务 setTimeout"] > ``` > [!tip] 记忆口诀 > **"同步先行,微任务跟进,宏任务殿后"** > > 输出顺序始终是:**2 → 3 → 5 → 4 → 1** 对于 Q43(var 闭包陷阱): ```js console.log(8); // 1. 同步输出 8 for (var i = 0; i < 5; i++) { // var 没有块级作用域,i 最终值为 5 setTimeout(() => console.log(i), 1000 * i); // 5个定时器全部注册为宏任务 } console.log(9); // 2. 同步输出 9 // 3. 1秒后依次输出 5,5,5,5,5 ``` ### Q27:对象引用赋值 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | A('teal') | | ✅ 正确答案 | B('red') | ```js let obj1 = { uname: 'teal' }; let obj2 = obj1; // 引用赋值,指向同一块内存 obj2.uname = 'red'; console.log(obj1.uname); // 'red' ← obj1 也变了! ``` ### Q01:Axios 拦截器的问题 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | D | | ✅ 正确答案 | D(B和C都对) | > [!note] 纠正说明 > 此题你答对了。关键两点: > - **token 过期应先尝试刷新**,而非直接跳转登录 > - **SPA 中应使用路由跳转**(如 `router.push('/login')`),`window.location.href` 会触发整页刷新,破坏 SPA 体验 ### Q12:响应拦截器异常处理 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | C | | ✅ 正确答案 | C(两个回调位置写法) | > [!note] 纠正说明 > 此题你答对了。注意签名顺序:`use(onFulfilled, onRejected)`——**先成功回调,后失败回调**。 ### Q100:Node.js 启用 ESM | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | C(--experimental-modules) | | ✅ 正确答案 | D(B和D均正确) | 两种方法均可启用 ESM: 1. `package.json` 中添加 `"type": "module"` 2. 使用 `.mjs` 扩展名 > [!warning] 注意 > `--experimental-modules` 是 Node 12~13 的临时标志,Node 14+ 已移除,不再是推荐做法。 --- ## 四、事件系统与 DOM/BOM ### Q02:取消默认事件的正确方法 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | C(preventDefault()) | | ✅ 正确答案 | C(preventDefault()) | > [!note] 纠正说明 > 此题你答对了。 > - `preventDefault()` → **阻止默认行为**(如链接跳转、表单提交) > - `stopPropagation()` → **阻止事件冒泡** > - `cancelBubble = true` → IE8 时代的旧写法 ### Q16:获取 CSS 样式的方法 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | A(getElementStyle()) | | ✅ 正确答案 | B(getComputedStyle()) | ```js // 标准写法 const style = getComputedStyle(element); console.log(style.fontSize); // 兼容性写法(IE8-) element.currentStyle?.fontSize; ``` ### Q17:TypeError 的产生场景 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | A(未定义变量操作) | | ✅ 正确答案 | B(将函数作为对象使用) | ```js TypeError 的典型场景: undefined.foo → ReferenceError(不是 TypeError!) fn() → TypeError(fn 不是函数却被当作函数调用) new undefined() → TypeError 'text'.split = 1 → TypeError(不可配置属性被修改) ``` > [!question] 💡 思考 > 为什么访问 `undefined.xxx` 抛的是 `ReferenceError` 而不是 `TypeError`? ### Q19:可继承的 CSS 属性 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | D(line-height) | | ✅ 正确答案 | C(border) | > [!memory] CSS 继承规则速记 > 文本相关属性(color/font/line-height/letter-spacing)**默认继承**。 > 盒模型属性(border/margin/padding/width/height)**不继承**。 ### Q20:选择器优先级 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | D(id) | | ✅ 正确答案 | A(style(行内样式最高)) | > [!memory] CSS 优先级从高到低 > ``` > !important > 行内 style > ID 选择器 > Class/属性/伪类 > 标签选择器 > 通配符 > ``` ### Q26:querySelector 选择第一个 box 类元素 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | C | | ✅ 正确答案 | C(document.querySelector('.box')) | > [!note] 纠正说明 > 此题你答对了。注意:`.box` 中的点 `.` 表示类选择器,不加点 `box` 会被当作标签名 ``。 ### Q30:事件委托中获得真实触发元素 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | C(target.name) | | ✅ 正确答案 | A(event.target.tagName) | ### Q31:阻止事件冒泡 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | C(preventPropagation()) | | ✅ 正确答案 | B(event.stopPropagation()) | > [!warning] 避坑 > DOM 规范中**不存在** `preventPropagation()` 这个方法。容易和 `preventDefault()` 混淆。 ### Q59:文件上传编码类型 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | A | | ✅ 正确答案 | A(enctype="multipart/form-data") | > [!note] 纠正说明 > 此题你答对了。只有文件上传时需要 `multipart/form-data`;普通表单用默认的 `application/x-www-form-urlencoded` 即可。 ### Q73:操作浏览器地址栏的对象 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | A(navigator) | | ✅ 正确答案 | D(location) | > [!memory] BOM 四大对象区分 > - **location**:URL 信息(搜索 `?`、哈希 `#`、跳转 `assign/replace`) > - **history**:历史栈(`back/forward/go`) > - **navigator**:浏览器信息(`userAgent/platform`) > - **screen**:屏幕尺寸 ### Q105:teleport 组件的理解 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | B | | ✅ 正确答案 | C(可以条件性启用) | > [!abstract] teleport 的关键特性 > - 传送的内容**保持与原组件的数据绑定**(响应式依然存在) > - 可以通过 `to` 属性指定任意合法选择器(不限于 body) > - 支持 `:disabled` 条件控制是否传送 ### Q107:Context 中修改 theme | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | B | | ✅ 正确答案 | B(需要将 setTheme 也传入 Context) | > [!note] 纠正说明 > 此题你答对了。Context 只传值不传方法,子组件就无法修改父组件的状态。正确做法是把 `[theme, setTheme]` 一起放入 value 对象。 --- ## 五、存储与定时器 ### Q33:localStorage 的限制 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | A(存储任意类型) | | ✅ 正确答案 | A(不能存储任意类型) | > [!warning] localStorage 只能存**字符串**! > 存入对象/数组会自动调用 `.toString()` 变成 `[object Object]`。正确做法: > ```js > localStorage.setItem('data', JSON.stringify({ a: 1 })); > const parsed = JSON.parse(localStorage.getItem('data')); > ``` ### Q34:定时器描述的错误选项 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | C | | ✅ 正确答案 | C(并非所有定时器都会立即执行) | `setTimeout(fn, 0)` 不代表立刻执行,而是放入宏任务队列等待本轮同步代码结束后再执行。 ### Q35:classList 切换类的方法 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | C | | ✅ 正确答案 | C(toggleClass 不存在) | > [!note] classList 的正确 API > > | 方法 | 说明 | > |------|------| > | `add()` | 添加类 | > | `remove()` | 删除类 | > | `toggle()` | **切换**(有则删,无则加) | > | `contains()` | 是否包含 | > | `replace(old, new)` | 替换类名 | > [!warning] 注意区分 > `toggleClass()` **不存在**于 DOM API 中,正确方法是 `classList.toggle()`(没有 Class 中间那个大写字母)。 ### Q108:自定义 Hook 的请求问题 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | B | | ✅ 正确答案 | B(每次渲染都会发起请求) | ```js // ❌ 错误:没有 useEffect 包裹 function useData(id) { fetch(`/api/data/${id}`).then(res => res.json()).then(setData); } // ✅ 正确:用 useEffect 控制时机 function useData(id) { const [data, setData] = useState(null); useEffect(() => { fetch(`/api/data/${id}`) .then(res => res.json()) .then(setData); }, [id]); // 依赖 id 变化才重新请求 } ``` --- ## 六、框架相关 ### Vue 专题 #### Q01(provide/inject)& Q101 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | A/C(父子通信 / props传递) | | ✅ 正确答案 | B(跨多层传递) | > [!abstract] provide/inject 适用场景 > > ```mermaid > graph TD > A["props drilling"] -->|"1-2层"| B["props 足够"] > A -->|"3+层"| C["provide/inject 更优雅"] > D["同层级兄弟"] --> E["提升状态到共同祖先"] > F["全局共享"] --> G["Pinia / Vuex"] > ``` #### Q102:reactive 解构导致响应式失效 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | B | | ✅ 正确答案 | B(解构会丢失响应式追踪) | ```js const state = reactive({ count: 0 }); // ❌ 解构后失去响应式 const { count } = state; // count 变成了普通数字 count++; // state.count 不变! // ✅ 正确做法 const { count } = toRefs(state); // toRefs 保留响应式 count.value++; // 同步更新 state.count ``` #### Q103:生命周期执行顺序 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | B | | ✅ 正确答案 | B(Child mounted → Parent mounted) | > [!abstract] 挂载顺序 > > ```mermaid > flowchart LR > A["父 setup 执行"] --> B["子 setup 执行"] > B --> C["子 template 渲染"] > C --> D["子 onMounted 执行"] > D --> E["父 template 渲染"] > E --> F["父 onMounted 执行"] > ``` #### Q106:API Key 泄露处理 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | B | | ✅ 正确答案 | B(在平台禁用并重新生成) | > [!note] 纠正说明 > 此题你答对了。密码 ≠ API Key,更改密码无法撤销已泄漏的 Key。 --- ### React 专题 #### Q43(var 闭包)& Q44 & Q06 & Q14 & Q27:JavaScript 基础贯穿 这几道题其实在考同一个内核:**JavaScript 的变量作用域和引用机制**。 | 题目 | 考查点 | 你的答案 | 正确答案 | |------|--------|---------|---------| | Q43 | var 循环闭包 | D | A | | Q44 | Promise + setTimeout | D | A | | Q06 | 值传递 | A | A | | Q14 | 引用传递 | C | C | | Q27 | 引用赋值 | A | B | #### Q46:v-bind vs v-on | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | C(v-on) | | ✅ 正确答案 | A(v-bind(动态属性绑定)) | #### Q62:useState 的作用 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | B(定义 props) | | ✅ 正确答案 | A(定义初始状态) | #### Q67:useEffect 清理副作用 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | C(useState) | | ✅ 正确答案 | A(返回一个函数) | #### Q70:React.memo 的作用 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | D(比较 refs) | | ✅ 正确答案 | A(比较 props,避免不必要重渲染) | #### Q72:子传父的实现方式 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | C(状态提升) | | ✅ 正确答案 | A(回调函数) | > [!question] 💡 思考 > "状态提升"和"回调函数"有什么区别?什么场景该用哪个? #### Q84:触发重渲染的条件 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | D(useRef变化) | | ✅ 正确答案 | A(父组件状态变化) | > [!warning] useRef 的变化**不会**触发重渲染——这正是它的价值所在。 #### Q98:浏览器原生支持的模块系统 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | A(CommonJS) | | ✅ 正确答案 | B(ESM) | ```html ``` CommonJS 是 Node.js 的规范,浏览器需要打包工具(Webpack/Vite)才能使用。 #### Q99:ESM 中报错的导出语法 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | D(export *) | | ✅ 正确答案 | C(export = { a: 1 }) | --- ## 七、Node.js 与构建工具 ### Q09:浏览器页面加载事件 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | A(DOMContentLoaded) | | ✅ 正确答案 | B(load(HTML + 所有外部资源)) | > [!abstract] 两个关键事件对比 > > ```mermaid > timeline > title 页面加载事件时间线 > HTML解析完成 : DOMContentLoaded > 图片/CSS/JS加载完 : load > ``` ### Q10:Node.js 能做什么 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | A | | ✅ 正确答案 | A(Node.js 不能操作 DOM) | ### Q49:执行 HTTP 请求的 Node 模块 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | D(net) | | ✅ 正确答案 | A(http) | ### Q50:FormData 添加键值对的方法 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | D(set()) | | ✅ 正确答案 | A(append()) | > [!warning] 注意区分 > Map 对象用 `set()`,但 FormData 用 **`append()`**。两者 API 不同。 ### Q53-56:Webpack 配置项速查 | 配置项 | 作用 | 你的答案 | |--------|------|---------| | devtool | 源代码映射 (sourcemap) | ❌ A | | externals | 定义外部依赖(不打包) | ✅ A | | splitChunks | 代码分割 | ✅ A | | resolve | 解析模块路径/别名 | ✅ A | | optimization | 优化打包 | ✅ C | ### Q11:Node.js 内置模块 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | D(dayjs) | | ✅ 正确答案 | D(dayjs(第三方库,非内置)) | ### Q57-58:Node.js 基础 | 题目 | 你的答案 | 正确答案 | |------|---------|---------| | module.exports | 导出公共接口 | ✅ A | | Node.js 是什么 | — | ✅ B | --- ## 八、其他知识点 ### Q28:自定义 data-* 属性 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | C(dataset 是函数) | | ✅ 正确答案 | D(dataset 返回 DOMMap 对象,不是函数) | ### Q29:innerText vs innerHTML | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | D | | ✅ 正确答案 | D(两者作用不一致,innerHTML 解析标签) | > [!note] 纠正说明 > 此题你答对了。`innerText` 只看纯文本,`innerHTML` 会解析并渲染 HTML 标签。 ### Q104:LLM 工作原理 | 项目 | 内容 | | ------ | -------- | | ❌ 你的答案 | B | | ✅ 正确答案 | B(下一个 token 的最大似然预测) | > [!note] 纠正说明 > 此题你答对了。LLM 不是"理解"语义,而是基于概率统计预测下一个词。 --- ## 高频考点速览 > [!summary] 测试中暴露的共性薄弱环节 | 类别 | 高频考点 | 掌握要点 | |------|---------|---------| | 事件循环 | 同步/微任务/宏任务顺序 | 同步 → Promise.then → setTimeout | | JavaScript 基础 | 值传递 vs 引用传递 | 基本类型传副本,引用类型传指针 | | 事件系统 | stopPropagation / preventDefault | 冒泡 vs 默认行为,千万别混 | | CSS | 优先级 & 继承规则 | 行内 > ID > Class > 标签;文本继承,盒模型不继承 | | HTTP | 400/401/403/404/500 | 4x 客户端错,5x 服务端错 | | Axios | 拦截器最佳实践 | 优先路由跳转、先刷新 token | | Vue | provide/inject | 专为跨多层通信设计 | | Vue | reactive 解构 | 用 toRefs 保留响应式 | | React | useEffect 清理 | return () => cleanup | | React | 状态不可变性 | setList([newArr]) 而非 push+原引用 | | React | useRef | 不触发重渲染 | | 模块系统 | ESM vs CommonJS | 浏览器原生 ESM,export/import | | webpack | devtool | sourcemap 调试用,不是开发工具 | --- ## 关联笔记 - [[hzh/EXAM]] - [[Frontend Fundamentals]] - [[JavaScript Event Loop]] - [[HTTP Status Codes]] - [[Vue Lifecycle]] - [[React Hooks Patterns]]