1314 lines
39 KiB
Markdown
1314 lines
39 KiB
Markdown
---
|
||
tags: [Frontend, Exam, Axios, React, Vue, JavaScript, CSS, Node.js, HTTP]
|
||
create time: 2026-04-30 14:30
|
||
---
|
||
|
||
# 武科大 - 第六次前端摸底测试(错题复盘)
|
||
|
||
## 概述
|
||
|
||
本文档记录金山考试 - 武科大第六次前端摸底测试的**全部 110 道单选题错题**。本次测试覆盖 JavaScript 基础、事件机制、异步编程、Axios/Fetch、浏览器 API、HTTP 协议、CSS、Vue 3、React Hooks、Node.js / npm、Webpack 等知识领域。
|
||
|
||
错题库已按**知识点主题**分组,每题附带详细解析、代码示例和图解,帮助查漏补缺。
|
||
|
||
> [!summary] 错误统计
|
||
> - **总题数**:110 道题
|
||
> - **错题数**:27 道
|
||
> - **正确率**:~75%
|
||
> - **薄弱领域**:事件机制理解、异步执行顺序、Vue/React 深度概念、HTTP 状态码区分
|
||
|
||
## 错题详解
|
||
|
||
### 一、事件处理
|
||
|
||
#### Q2 — 取消默认事件 vs 阻止冒泡 ❌ 答 A,正确 C
|
||
|
||
> **题目**:如何取消默认事件效果?
|
||
>
|
||
> | 选项 | 内容 |
|
||
> |------|------|
|
||
> | A | `cancelBubble=true` |
|
||
> | B | `stopPropagation()` |
|
||
> | C | `preventDefault()` ✅ |
|
||
> | D | `return` |
|
||
|
||
> [!warning] 核心混淆
|
||
> `cancelBubble` 和 `stopPropagation()` 是**阻止事件冒泡**,不是取消默认行为!
|
||
>
|
||
> - `e.preventDefault()` → 取消元素的**默认动作**(如 `<a>` 跳转、`<form>` 提交)
|
||
> - `e.stopPropagation()` → 停止事件向**父元素传播**(不冒泡了)
|
||
> - `e.cancelBubble = true` → IE 旧版写法,等同于 `stopPropagation()`
|
||
> - 在行内 `onclick="return false"` 可以等效于 `preventDefault() + stopPropagation()`
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
subgraph "事件流"
|
||
A[捕获阶段] --> B[目标阶段]
|
||
B --> C["冒泡阶段"]
|
||
end
|
||
|
||
preventDefault["preventDefault()\n→ 阻止默认行为\n不影响冒泡"] -.-> B
|
||
stopPropagation["stopPropagation()\n→ 阻止向上冒泡\n不影响默认行为"] -.-> C
|
||
|
||
style preventDefault fill:#EF4444,color:#fff
|
||
style stopPropagation fill:#3B82F6,color:#fff
|
||
```
|
||
|
||
> [!tip] 常见默认行为
|
||
> - `<a href>` 点击跳转
|
||
> - `<form>` 提交刷新页面
|
||
> - 右键菜单
|
||
> - 文本选择拖拽
|
||
> - 鼠标滚轮页面滚动
|
||
|
||
---
|
||
|
||
#### Q19 — CSS 继承性 ❌ 答 D,正确 C
|
||
|
||
> **题目**:下面哪个属性不会继承?
|
||
>
|
||
> | 选项 | 内容 |
|
||
> |------|------|
|
||
> | A | `color` |
|
||
> | B | `font-size` |
|
||
> | C | `border` ✅ |
|
||
> | D | `line-height` |
|
||
|
||
> [!answer] 解析
|
||
> CSS 中只有**部分属性会继承**给子元素。可继承的属性主要是与**文本渲染**相关的:`color`、`font-*`、`line-height`、`text-*`、`visibility` 等。而布局相关属性几乎都不继承:`border`、`margin`、`padding`、`width`、`height`、`background` 等。
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "可继承的属性"
|
||
T1["color"]
|
||
T2["font-size / font-family"]
|
||
T3["line-height"]
|
||
T4["text-align"]
|
||
end
|
||
|
||
subgraph "不可继承的属性 ← 重点记 border!"
|
||
B1["border"]
|
||
B2["margin / padding"]
|
||
B3["width / height"]
|
||
B4["background"]
|
||
end
|
||
|
||
style B1 fill:#EF4444,color:#fff
|
||
```
|
||
|
||
---
|
||
|
||
#### Q16 — 获取 CSS 样式 ❌ 答 A,正确 B
|
||
|
||
> **题目**:下面哪个方法可以获取元素的 CSS 样式?
|
||
>
|
||
> | 选项 | 内容 |
|
||
> |------|------|
|
||
> | A | `getElementStyle()` |
|
||
> | B | `getComputedStyle()` ✅ |
|
||
> | C | `getStyle()` |
|
||
> | D | `getCurrentStyle()` |
|
||
|
||
> [!answer] 解析
|
||
> - **标准方法**:`window.getComputedStyle(element)` → 返回所有最终计算后的样式
|
||
> - **IE8 兼容**:`element.currentStyle`(已过时,仅 IE 支持)
|
||
> - A、C 都不是原生 API
|
||
|
||
```js
|
||
const el = document.querySelector('.box');
|
||
const styles = window.getComputedStyle(el);
|
||
console.log(styles.backgroundColor); // 计算后的值,如 "rgb(255, 0, 0)"
|
||
```
|
||
|
||
> [!tip] `getComputedStyle` vs `el.style`
|
||
> | 方法 | 能读什么 | 返回值类型 |
|
||
> |------|---------|-----------|
|
||
> | `el.style.prop` | 只读元素**内联样式**(`style="..."`) | 字符串 |
|
||
> | `getComputedStyle()` | 读**所有生效**样式(含 CSS 文件、类) | CSSStyleDeclaration 对象 |
|
||
|
||
---
|
||
|
||
#### Q31 — 阻止事件冒泡 ❌ 答 C,正确 B
|
||
|
||
> **题目**:用于阻止事件冒泡的方法?
|
||
>
|
||
> | 选项 | 内容 |
|
||
> |------|------|
|
||
> | A | `事件对象.stopDeafault()` |
|
||
> | B | `事件对象.stopPropagation()` ✅ |
|
||
> | C | `事件对象.preventPropagation()` |
|
||
> | D | `事件对象.preventDefault()` |
|
||
|
||
> [!answer] 解析
|
||
> 注意拼写!`stopPropagation()` 是标准方法。A 选项 `stopDeafault` 是个拼写陷阱(应为 `preventDefault`),D 是阻止默认行为而非冒泡。
|
||
|
||
---
|
||
|
||
#### Q32 — 事件委托 ❌ 答 D,正确 D(此题作答正确,但文档中标注为错题——请确认)
|
||
|
||
> **题目**:关于事件委托,说法错误的是?
|
||
>
|
||
> | 选项 | 内容 |
|
||
> |------|------|
|
||
> | D(错误说法) | 事件委托中的 `this` 与 `e.target` 指向同一个对象,它们可以随意互换 |
|
||
|
||
> [!answer] 解析
|
||
> 事件委托中绑定的回调函数的 `this` 指向**注册事件的父元素**,而 `e.target` 指向**实际触发事件的子元素**——两者可能不同!
|
||
|
||
```js
|
||
ul.addEventListener('click', function(e) {
|
||
console.log(this); // <ul>(委托绑定的元素)
|
||
console.log(e.target); // <li>(实际点击的元素)
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
#### Q17 — TypeError ❌ 答 A(其实正确),待核实
|
||
|
||
> [!note] 本题标注有误:正确答案应为 **B**(将函数作为对象使用会抛 TypeError)。`undefined` 变量操作抛出的是 `ReferenceError`。原题答案可能有误。
|
||
|
||
---
|
||
|
||
### 二、JavaScript 数据类型与作用域
|
||
|
||
#### Q7 — 不属于 JS 对象数据类型的 ❌ 答 A,正确 D
|
||
|
||
> **题目**:下列不属于 JS 对象(引用)数据类型的是?
|
||
>
|
||
> | 选项 | 内容 |
|
||
> |------|------|
|
||
> | A | RegExp |
|
||
> | B | Function |
|
||
> | C | Array |
|
||
> | D | String ✅(原始类型) |
|
||
|
||
> [!answer] 解析
|
||
> JS 的数据类型分两类:
|
||
>
|
||
> ```mermaid
|
||
> graph TD
|
||
> All["JS 数据类型"] --> Prim["原始类型 Primitive"]
|
||
> All --> Ref["引用类型 Object"]
|
||
>
|
||
> Prim --> P1["String"]
|
||
> Prim --> P2["Number"]
|
||
> Prim --> P3["Boolean"]
|
||
> Prim --> P4["null"]
|
||
> Prim --> P5["undefined"]
|
||
> Prim --> P6["Symbol"]
|
||
> Prim --> P7["BigInt"]
|
||
>
|
||
> Ref --> R1["Object"]
|
||
> Ref --> R2["Array"]
|
||
> Ref --> R3["Function"]
|
||
> Ref --> R4["RegExp"]
|
||
> Ref --> R5["Date"]
|
||
>
|
||
> style P1 fill:#EF4444,color:#fff
|
||
> style R2 fill:#4FC08D,color:#fff
|
||
> style R3 fill:#4FC08D,color:#fff
|
||
> style R4 fill:#4FC08D,color:#fff
|
||
> ```
|
||
>
|
||
> `String` 是**原始类型**( primitive ),而 RegExp、Function、Array 都是对象类型(继承自 Object)。
|
||
|
||
---
|
||
|
||
#### Q23 — typeof +'136' ❌ 答 D,正确 B
|
||
|
||
> **题目**:`console.log(typeof +'136')` 输出的结果?
|
||
>
|
||
> > [!tip] 一元运算符 `+` 会将字符串转为数字
|
||
> > `'136'` → `Number('136')` → `136`,所以 `typeof 136` → `"number"`
|
||
|
||
---
|
||
|
||
#### Q24 — 闭包作用域 ❌ 答 A(实际作答正确,待核实)
|
||
|
||
> [!note] `f2` 访问的是外层 `f1` 中的 `num = 123`,通过闭包实现。输出 123。若答案为 A 则作答正确。
|
||
|
||
---
|
||
|
||
### 三、异步编程 & 执行顺序
|
||
|
||
#### Q13 & Q44 — Promise + setTimeout 执行顺序 ❌ 答 C/Q44答D,正确 A/C
|
||
|
||
> **题目**(Q13 等价于 Q44):以下代码输出顺序?
|
||
>
|
||
> ```js
|
||
> setTimeout(function () { console.log(1); }, 0);
|
||
> new Promise(function executor(resolve) {
|
||
> console.log(2);
|
||
> for (var i = 0; i < 10000; i++) { i == 9999 && resolve(); }
|
||
> console.log(3);
|
||
> }).then(function () { console.log(4); });
|
||
> console.log(5);
|
||
> ```
|
||
>
|
||
> **答案:`2 3 5 4 1`**
|
||
|
||
> [!danger] 高频考点:JS 执行模型
|
||
> JS 是单线程的,事件循环 Event Loop 的执行优先级如下:
|
||
>
|
||
> ```mermaid
|
||
> flowchart TD
|
||
> Sync["同步代码 → 立即执行"] --> Micro["微任务 Microtask<br/>Promise.then / queueMicrotask"]
|
||
> Micro --> Macro["宏任务 Macrotask<br/>setTimeout / setInterval"]
|
||
>
|
||
> style Sync fill:#4FC08D,color:#fff
|
||
> style Micro fill:#EAB308,color:#000
|
||
> style Macro fill:#3B82F6,color:#fff
|
||
> ```
|
||
>
|
||
> **逐行分析:**
|
||
> 1. `setTimeout(...0)` → 注册为**宏任务**,放入定时器队列
|
||
> 2. `new Promise(...)` → 构造函数是**同步执行**的 → 打印 `2`
|
||
> 3. for 循环内调用了 `resolve()` → 但 `.then()` 是**微任务**,不会立刻执行
|
||
> 4. `console.log(3)` → 同步代码 → 打印 `3`
|
||
> 5. `console.log(5)` → 同步代码 → 打印 `5`
|
||
> 6. 同步代码执行完毕 → 清空**微任务** → `.then(() => 4)` 执行 → 打印 `4`
|
||
> 7. 微任务清空 → 进入下一轮宏任务 → `setTimeout` 回调 → 打印 `1`
|
||
>
|
||
> **顺序:2 → 3 → 5 → 4 → 1**
|
||
|
||
> [!tip] 记忆口诀
|
||
> **"同步先走,微任务跟上,宏任务压轴"**
|
||
|
||
---
|
||
|
||
#### Q43 — var + setTimeout 闭包问题 ❌ 答 B,正确 A
|
||
|
||
> **题目**:下面的输出结果是什么?
|
||
>
|
||
> ```js
|
||
> console.log(8);
|
||
> for (var i = 0; i < 5; i++) {
|
||
> setTimeout(function () { console.log(i); }, 1000 * i);
|
||
> }
|
||
> console.log(9);
|
||
> ```
|
||
>
|
||
> **答案:`8, 9, 5, 5, 5, 5, 5`**
|
||
|
||
> [!warning] 经典闭包陷阱
|
||
> `var` 声明的 `i` 是**函数作用域**(全局)变量,所有 setTimeout 回调共享同一个 `i`。当回调执行时,for 循环早已结束,`i === 5`(条件 `i < 5` 不成立时的值)。
|
||
>
|
||
> **解决方法:**
|
||
> ```js
|
||
> // 方案1:let(块级作用域)
|
||
> for (let i = 0; i < 5; i++) { /* 每个循环创建独立 i */ }
|
||
>
|
||
> // 方案2:IIFE 闭包保存快照
|
||
> for (var i = 0; i < 5; i++) {
|
||
> (function(j) { setTimeout(() => console.log(j), 1000 * j); })(i);
|
||
> }
|
||
> ```
|
||
|
||
---
|
||
|
||
#### Q6 — 参数传值 vs 传引用 ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] 函数参数传值,`num = num + 1` 只修改局部变量,原值不变。答案 A 正确。
|
||
|
||
---
|
||
|
||
#### Q14 — 数组传引用 ❌ 答 C(实际正确,待核实)
|
||
|
||
> [!note] 数组是引用类型,push 直接修改原数组,答案 C 正确。
|
||
|
||
---
|
||
|
||
#### Q27 — 对象引用 ❌ 答 B(实际正确,待核实)
|
||
|
||
> [!note] `obj2 = obj1` 是引用赋值,修改 obj2.uname 也影响 obj1。答案 B 正确。
|
||
|
||
---
|
||
|
||
### 四、浏览器 API & BOM
|
||
|
||
#### Q5 — AJAX 核心对象 ❌ 答 C(实际正确,待核实)
|
||
|
||
> [!note] `XMLHttpRequest` 首字母大写全称才是标准答案,`xhr` 只是变量名缩写。答案 C 正确。
|
||
|
||
---
|
||
|
||
#### Q9 — load vs DOMContentLoaded ❌ 答 B(实际正确,待核实)
|
||
|
||
> [!note] `window.onload`(即 `load` 事件)在 HTML 及其所有外部资源(图片、样式表、iframe)全部加载完毕后触发。`DOMContentLoaded` 只需 DOM 树构建完成即可。题目问的是"HTML + 所有外部资源都加载完成",所以是 `load`。
|
||
|
||
---
|
||
|
||
#### Q73 — BOM 中操作地址栏的对象 ❌ 答 D(实际正确,待核实)
|
||
|
||
> [!note] `location` 对象提供 URL 相关信息和操作。
|
||
|
||
---
|
||
|
||
#### Q36 — :nth-child 伪类 ❌ 答 D,正确 C
|
||
|
||
> **题目**:`:nth-child()` 用于选择什么?
|
||
>
|
||
> > [!answer] `:nth-child(n)` 根据**序号**匹配子元素。例如 `:nth-child(2)` 选中第 2 个子元素,`:nth-child(odd)` 选奇数位。它不看元素类型,只看位置。
|
||
|
||
---
|
||
|
||
#### Q37 — text-overflow 用途 ❌ 答 C(实际正确,待核实)
|
||
|
||
> [!note] `text-overflow: ellipsis` 用于隐藏超长文本并用省略号替代,需配合 `white-space: nowrap; overflow: hidden` 使用。
|
||
|
||
---
|
||
|
||
#### Q38 — AJAX 请求完成事件 ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] `xhr.onload` 在请求成功完成后触发(readyState === 4)。
|
||
|
||
---
|
||
|
||
#### Q40 — 解析 JSON 响应的对象 ❌ 答 B,正确 A
|
||
|
||
> **题目**:接收到 `xhr.responseText` 后使用哪个对象解析?
|
||
>
|
||
> > [!answer] `JSON.parse()`。xhr 收到的永远是字符串,需要手动 `JSON.parse(responseText)` 转换为 JS 对象。注意不要和 `eval()` 混用——`JSON.parse()` 更安全、更快。
|
||
|
||
---
|
||
|
||
#### Q28 — 自定义 data- 属性 ❌ 答 D(实际正确,待核实)
|
||
|
||
> [!note] `dataset` 是一个 `DOMStringMap` 对象,不是函数。通过 `element.dataset.id` 访问 `data-id` 的值。
|
||
|
||
---
|
||
|
||
#### Q29 — innerText vs innerHTML ❌ 答 D(实际正确,待核实)
|
||
|
||
> [!note] `innerText` 只处理纯文本,不解析标签;`innerHTML` 会解析 HTML 标签。D 说两者作用一致是错误的。
|
||
|
||
---
|
||
|
||
#### Q30 — 事件委托获取目标元素 ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] `event.target` 指向真正触发事件的元素,`.tagName` 获取标签名。
|
||
|
||
---
|
||
|
||
#### Q33 — localStorage vs sessionStorage ❌ 答 D,正确 A
|
||
|
||
> **题目**:关于 localStorage/sessionStorage,下列说法错误的是?
|
||
>
|
||
> > [!answer] A 错误——localStorage/sessionStorage **只能存储字符串类型**的数据。存储对象需要先 `JSON.stringify()`,读取后 `JSON.parse()`。虽然看起来像能存任意类型,但实际上底层全部存为字符串。
|
||
|
||
---
|
||
|
||
#### Q34 — 定时器 ❌ 答 C(实际正确,待核实)
|
||
|
||
> [!note] `setTimeout` 不是立即执行的,它会在延迟时间后将回调加入宏任务队列等待执行。
|
||
|
||
---
|
||
|
||
#### Q35 — classList 方法 ❌ 答 C(实际正确,待核实)
|
||
|
||
> [!note] 切换类的方法是 `classList.toggle()`,没有 `toggleClass()` 这个方法名。
|
||
|
||
---
|
||
|
||
### 五、HTTP & 网络
|
||
|
||
#### Q51 — HTTP 400 状态码 ❌ 答 B,正确 D
|
||
|
||
> **题目**:HTTP 状态码 400 表示什么意思?
|
||
>
|
||
> > [!warning] 高频易混的四组 4xx 状态码
|
||
> >
|
||
> > | 状态码 | 含义 | 典型场景 |
|
||
> > |--------|------|----------|
|
||
> > | **400** | Bad Request | 请求格式错误、参数校验失败 |
|
||
> > | **401** | Unauthorized | 未认证/token 过期 |
|
||
> > | **403** | Forbidden | 无权限访问(已认证但级别不够) |
|
||
> > | **404** | Not Found | 资源不存在 |
|
||
>
|
||
> 本题容易把 400(请求参数错误)和 401(token 过期)搞混。记住:**400 是客户端语法/参数问题,401 是身份验证问题**。
|
||
|
||
---
|
||
|
||
#### Q52 — Content-Type 的作用 ❌ 答 D,正确 A
|
||
|
||
> **题目**:Content-Type 通常用于指定什么?
|
||
>
|
||
> > [!answer] **请求体的类型**。告诉服务器"我的请求体是 JSON / form-urlencoded / multipart/form-data"。
|
||
> >
|
||
> > 常见值:
|
||
> > - `application/json` — 发送 JSON 数据
|
||
> > - `application/x-www-form-urlencoded` — 传统表单提交
|
||
> > - `multipart/form-data` — 文件上传
|
||
> > - `text/plain` — 纯文本
|
||
|
||
---
|
||
|
||
### 六、Axios & 请求封装
|
||
|
||
#### Q12 — 响应拦截器错误处理 ❌ 答 A,正确 C
|
||
|
||
> **题目**:响应拦截中想处理异常且仍被 catch 捕获,正确的是?
|
||
>
|
||
> > [!answer] `axios.interceptors.response.use(() => {}, error => { return Promise.reject(error) })`
|
||
> >
|
||
> > 关键点:
|
||
> > 1. `response.use` 接收**两个参数**:第一个是成功回调,第二个是错误回调
|
||
> > 2. 错误回调中必须 `return Promise.reject(error)` 才能让下游 `.catch()` 收到
|
||
>
|
||
> ```js
|
||
> // 正确写法 —— 双参数形式
|
||
> axios.interceptors.response.use(
|
||
> response => response, // ✅ 成功回调(第一参数)
|
||
> error => Promise.reject(error) // ✅ 失败回调(第二参数)
|
||
> );
|
||
>
|
||
> // 错误写法 —— 只给了一个参数,当成成功回调处理了
|
||
> axios.interceptors.response.use(error => {...}) // ❌ error 被当成成功处理
|
||
> ```
|
||
|
||
---
|
||
|
||
### 七、Node.js & npm
|
||
|
||
#### Q49 — Node.js 发 HTTP 请求的模块 ❌ 答 D,正确 A
|
||
|
||
> **题目**:Node.js 中允许执行 HTTP 请求的内置模块?
|
||
>
|
||
> > [!answer] `http` 模块。它提供 `http.request()` 和 `http.get()` 方法用于发起 HTTP 请求。`https` 模块也存在,但 `http` 是最通用的标准答案。
|
||
>
|
||
> ```js
|
||
> import http from 'node:http';
|
||
>
|
||
> const req = http.get('http://example.com', (res) => {
|
||
> let data = '';
|
||
> res.on('data', chunk => data += chunk);
|
||
> res.on('end', () => console.log(JSON.parse(data)));
|
||
> });
|
||
> ```
|
||
|
||
---
|
||
|
||
#### Q10 — Node.js 描述不正确的一项 ❌ 答 D,正确 A
|
||
|
||
> **题目**:下列关于 Node.js 描述不正确的是?
|
||
>
|
||
> > [!answer] Node.js **不能操作 DOM**。DOM(Document Object Model)是浏览器提供的 API,Node.js 运行在服务端没有浏览器环境。Node.js 可以做文件操作 (`fs`)、发请求 (`http/https`)、爬虫等。
|
||
>
|
||
> > [!tip] 如果非要在 Node.js 中操作 DOM,可以用 `jsdom` 库模拟浏览器环境。
|
||
|
||
---
|
||
|
||
#### Q11 — 非 Node.js 内置模块 ❌ 答 D(实际正确,待核实)
|
||
|
||
> [!note] `dayjs` 是第三方库,需要通过 npm 安装。path/url/http 都是内置模块。
|
||
|
||
---
|
||
|
||
### 八、Vue 3
|
||
|
||
#### Q41 — onMounted vs mounted ❌ 答 D,正确 A
|
||
|
||
> **题目**:Vue 3 Composition API 中组件挂载后调用的钩子?
|
||
>
|
||
> > [!answer] Vue 3 **Composition API**(`<script setup>` / `setup()`)中使用 `onMounted()` 以函数形式调用。
|
||
> > Vue 2 Options API 中使用 `mounted: function() {}` 配置项形式。
|
||
> >
|
||
> > 两套 API 的区别:
|
||
> > ```js
|
||
> > // Vue 2 Options API
|
||
> > export default {
|
||
> > mounted() { console.log('组件已挂载'); }
|
||
> > }
|
||
> >
|
||
> > // Vue 3 Composition API
|
||
> > import { onMounted } from 'vue';
|
||
> > onMounted(() => { console.log('组件已挂载'); });
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q95 — script setup 错误说法 ❌ 答 D,正确 C
|
||
|
||
> **题目**:关于 `<script setup>` 的说法错误的是?
|
||
>
|
||
> > [!answer] `<script setup>` **不需要 return**。它会自动暴露顶层绑定(变量、函数),因此 C 说"需要使用 return 暴露数据"是错误的。
|
||
> >
|
||
> > ```html
|
||
> > <script setup>
|
||
> > import { ref } from 'vue';
|
||
> >
|
||
> > const count = ref(0); // ✅ 自动暴露,模板中可直接用 count
|
||
> > const increment = () => count.value++; // ✅ 自动暴露
|
||
> > // ❌ 不需要 return { count, increment }
|
||
> > </script>
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q102 — reactive 解构导致响应式失效 ❌ 答 A,正确 B
|
||
|
||
> **题目**:哪种情况可能导致响应式失效?
|
||
>
|
||
> > [!warning] **reactive 对象解构会丢失响应性!**
|
||
> >
|
||
> > ```js
|
||
> > const state = reactive({ count: 0, name: 'vue' });
|
||
> >
|
||
> > // ❌ 解构后 count 是普通 number,不再响应
|
||
> > const { count } = state;
|
||
> > count++; // ❌ 不会触发视图更新
|
||
> >
|
||
> > // ✅ 正确做法:用 toRef / toRefs
|
||
> > const count = toRef(state, 'count');
|
||
> > count.value++; // ✅ 保持响应式
|
||
> > ```
|
||
> >
|
||
> > **原理**:解构时提取的是值的副本,断开了与 reactive Proxy 的联系。Object.assign 会触发 Proxy set trap,所以不受影响。
|
||
|
||
---
|
||
|
||
#### Q103 — Vue 生命周期顺序 ❌ 答 D,正确 B
|
||
|
||
> **题目**:父子组件 mounted 执行顺序?
|
||
>
|
||
> > [!answer] **子组件先 mounted,父组件后 mounted。**
|
||
> >
|
||
> > ```mermaid
|
||
> > flowchart TD
|
||
> > A["父组件 setup"] --> B["子组件 setup"]
|
||
> > B --> C["子组件 render + mount"]
|
||
> > C --> D["子组件 onMounted 🔔"]
|
||
> > D --> E["父组件 render + mount"]
|
||
> > E --> F["父组件 onMounted 🔔"]
|
||
> >
|
||
> > style D fill:#4FC08D,color:#fff
|
||
> > style F fill:#3B82F6,color:#fff
|
||
> > ```
|
||
> >
|
||
> > 记忆:**先子后代,先上后下**。
|
||
|
||
---
|
||
|
||
#### Q105 — Teleport ❌ 答 B,正确 C
|
||
|
||
> **题目**:关于 teleport 的正确理解?
|
||
>
|
||
> > [!answer]
|
||
> > - `teleport` 可以使用 `to` prop 动态禁用(`<Teleport :to="disabled ? '#default' : '#modal'" />`)✅
|
||
> > - 传送的内容**保持**与原组件的数据绑定 ❌(A 说只能传 body 是错的)
|
||
> > - 一个组件可以有多个 teleport ❌
|
||
> >
|
||
> > > [!tip] Teleport 本质
|
||
> > > Teleport 只是改变 DOM 的物理位置,组件的逻辑归属和数据绑定完全不变,就像"搬家但户口没变"。
|
||
|
||
---
|
||
|
||
#### Q101 — provide/inject 适用场景 ❌ 答 C,正确 B
|
||
|
||
> **题目**:何时用 provide/inject 比 props 更合适?
|
||
>
|
||
> > [!answer] 当**跨多层组件**(深嵌套)传递数据时,props drilling 会让中间层不得不透传 props,这时 provide/inject 可以直接从祖先注入到任意后代,跳过中间层。
|
||
|
||
---
|
||
|
||
#### Q96 — Koa 中间件执行顺序 ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] Koa 中间件像洋葱圈模型:
|
||
>
|
||
> ```
|
||
> ┌─────────────────────────────┐
|
||
> │ middlewares in order: │
|
||
> │ [1] → [3] │
|
||
> │ ...body... │
|
||
> │ [4] ← [2] │
|
||
> └─────────────────────────────┘
|
||
> ```
|
||
> 输出:`1 → 3 → 4 → 2`(before next → after next)
|
||
|
||
---
|
||
|
||
### 九、React
|
||
|
||
#### Q68 — useEffect 只执行一次 ❌ 答 C,正确 A
|
||
|
||
> **题目**:useEffect 如何执行只运行一次的副作用?
|
||
>
|
||
> > [!answer] 传入空依赖数组 `[]`。这等价于 Class 组件的 `componentDidMount`。
|
||
> >
|
||
> > ```js
|
||
> > useEffect(() => {
|
||
> > // 只在组件挂载时执行一次
|
||
> > fetchData();
|
||
> > }, []); // ← 空数组 = 只在首次渲染后执行
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q72 — 子传父方式 ❌ 答 D,正确 A
|
||
|
||
> **题目**:子传父在 React 中通常通过什么实现?
|
||
>
|
||
> > [!answer] **回调函数(Callback Props)**。父组件定义一个函数,通过 props 传给子组件,子组件调用该函数并携带数据。这是 React 单向数据流的核心模式。
|
||
>
|
||
> ```jsx
|
||
> // 父组件
|
||
> function Parent() {
|
||
> const handleData = (childData) => console.log(childData);
|
||
> return <Child onSend={handleData} />;
|
||
> }
|
||
>
|
||
> // 子组件
|
||
> function Child({ onSend }) {
|
||
> return <button onClick={() => onSend('hello')} />;
|
||
> }
|
||
> ```
|
||
|
||
---
|
||
|
||
#### Q86 — Fragment 主要作用 ❌ 答 C,正确 D
|
||
|
||
> **题目**:Fragment 的主要作用?
|
||
>
|
||
> > [!answer] Fragment (`<>...</>`) 让组件返回多个子元素时**不添加额外 DOM 节点**。常用于表格 `<tr>`、列表项等对 DOM 层级有严格要求的场景。
|
||
> >
|
||
> > ```jsx
|
||
> > // 不用 Fragment —— 多一层 div
|
||
> > function Table() {
|
||
> > return (<div><tr/><tr/></div>); // ❌ 不合法
|
||
> > }
|
||
>
|
||
> > // 用 Fragment —— 直接渲染子元素
|
||
> > function Table() {
|
||
> > return (<><tr/><tr/></>); // ✅ 合法
|
||
> > }
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q78 — useEffect 清理函数 ❌ 答 A,正确 C
|
||
|
||
> **题目**:关于 useEffect 清理函数的说法正确的是?
|
||
>
|
||
> > [!answer] 清理函数在**下次 effect 执行前**和**组件卸载时**都会执行。
|
||
> >
|
||
> > ```js
|
||
> > useEffect(() => {
|
||
> > const timer = setInterval(() => {}, 1000);
|
||
> >
|
||
> > // 清理函数
|
||
> > return () => clearInterval(timer);
|
||
> > // ↑ 在下次 effect 执行前 + 组件卸载时 都会执行
|
||
> > }, [dep]); // dep 变化时也会触发清理
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q79 — 自定义 Hook ❌ 答 B,正确 A
|
||
|
||
> **题目**:关于自定义 Hook 的说法正确的是?
|
||
>
|
||
> > [!answer] 自定义 Hook **必须以 `use` 开头命名**。这样 React 才能在编译时识别它是一个 Hook,并应用 Hook 规则(不能在条件语句或循环中使用)。自定义 Hook 只能在函数组件或其他 Hook 中调用,**不能在类组件中使用**。
|
||
|
||
---
|
||
|
||
#### Q80 — props 特性 ❌ 答 C,正确 B
|
||
|
||
> **题目**:组件的 props 特性是?
|
||
>
|
||
> > [!answer] props 是**只读的(不可变)**。这是 React 单项数据流的基石——父组件控制 props,子组件只能读取不能修改。如需更新,父组件应通过 state 变化重新传递新值。
|
||
|
||
---
|
||
|
||
#### Q82 — 路由根组件 ❌ 答 A,正确 B
|
||
|
||
> **题目**:包裹整个应用路由的根组件?
|
||
>
|
||
> > [!answer] `BrowserRouter`(React Router v6)包装整个应用,监听 URL 变化并提供路由上下文。v5 中叫 `Router`。
|
||
|
||
---
|
||
|
||
#### Q90 — React Router 核心原理 ❌ 答 A,正确 C
|
||
|
||
> **题目**:React Router 基于哪种机制?
|
||
>
|
||
> > [!answer] **URL 变化监听 + 组件映射**。Browser History API(`popstate` 事件)监听 URL 变化,然后将当前路径与 Route 配置进行匹配,渲染对应的组件。
|
||
|
||
---
|
||
|
||
#### Q91 — 编程式导航钩子 ❌ 答 D,正确 A
|
||
|
||
> **题目**:编程式导航使用的钩子?
|
||
>
|
||
> > [!answer] `useNavigate()`。返回一个 navigate 函数,可用于按钮点击等交互场景中跳转。
|
||
> >
|
||
> > ```js
|
||
> > import { useNavigate } from 'react-router-dom';
|
||
> >
|
||
> > function MyButton() {
|
||
> > const navigate = useNavigate();
|
||
> > return <button onClick={() => navigate('/dashboard')}>Go</button>;
|
||
> > }
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q107 — Context 中如何修改 theme ❌ 答 D,正确 B
|
||
|
||
> **题目**:Child 中如何修改 theme?
|
||
>
|
||
> > [!answer] 需要将 `setTheme` 也通过 Context 传递下去,或者在 Provider 中把 `[theme, setTheme]` 一起作为 value 传递。
|
||
> >
|
||
> > ```jsx
|
||
> > <ThemeContext.Provider value={{ theme, setTheme }}>
|
||
> > <Child />
|
||
> > </ThemeContext.Provider>
|
||
> >
|
||
> > // Child 中
|
||
> > const { theme, setTheme } = useContext(ThemeContext);
|
||
> > // ✅ 可以通过 setTheme 修改
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q108 — 自定义 Hook 的问题 ❌ 答 B(实际正确,待核实)
|
||
|
||
> [!note] Hook 内的 fetch 不在 useEffect 中包裹,每次渲染都会重新发起请求。正确写法应使用 `useEffect`。
|
||
|
||
---
|
||
|
||
#### Q109 — 直接 push 数组更新状态 ❌ 答 A,正确 B
|
||
|
||
> **题目**:`list.push(4); setList(list);` 会发生什么?
|
||
>
|
||
> > [!warning] **React State 是不可变的!**
|
||
> >
|
||
> > ```js
|
||
> > list.push(4); // 原地修改数组
|
||
> > setList(list); // 传给 React 的还是同一个引用
|
||
> > // React 做浅比较发现引用相同 → 不会重渲染
|
||
> > ```
|
||
> >
|
||
> > **正确写法:**
|
||
> > ```js
|
||
> > setList([...list, 4]); // 方案1:展开新数组
|
||
> > setList(prev => prev.concat(4)); // 方案2:函数式更新
|
||
> > ```
|
||
|
||
---
|
||
|
||
### 十、ESM & CommonJS
|
||
|
||
#### Q92 — CommonJS 导出语法 ❌ 答 D,正确 B
|
||
|
||
> **题目**:以下哪种导出语法属于 CommonJS 规范?
|
||
>
|
||
> > [!answer] `exports.name = 'John';` 是 CommonJS 的命名导出写法。CommonJS 用 `module.exports` / `exports` 导出,用 `require()` 导入。
|
||
> >
|
||
> > ```js
|
||
> > // CommonJS
|
||
> > exports.name = 'John';
|
||
> > module.exports = { name };
|
||
> > require('./module');
|
||
> >
|
||
> > // ESM(现代标准)
|
||
> > export const name = 'John';
|
||
> > export default function() {};
|
||
> > import { name } from './module';
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q99 — ESM 会报错的导出 ❌ 答 B,正确 C
|
||
|
||
> **题目**:以下哪种导出方式在 ESM 中会报错?
|
||
>
|
||
> > [!answer] `export = { a: 1 }` 是 TypeScript 的语法,不是 ESM 标准语法。ESM 不支持 `export =`。
|
||
> >
|
||
> > ESM 的标准导出:
|
||
> > ```js
|
||
> > export default 42; // 默认导出
|
||
> > export const a = 1, b = 2; // 具名导出(一行多变量)
|
||
> > export * from './module'; // 全部重新导出
|
||
> > ```
|
||
|
||
---
|
||
|
||
### 十一、其他高频考点速查
|
||
|
||
#### Q3 — 解决跨域 ❌ 答 D(实际正确,待核实)
|
||
|
||
> [!note] axios 本身不具备跨域能力,jsonp/server cors/server proxy 才是真正的跨域方案。
|
||
|
||
---
|
||
|
||
#### Q4 — 终止 xhr 请求 ❌ 答 A,正确 D
|
||
|
||
> **题目**:可以终止请求的 XHR 函数?
|
||
>
|
||
> > [!answer] `xhr.abort()`。调用后立即停止请求,触发 `onerror` 和 `ontimeout`。
|
||
> >
|
||
> > ```js
|
||
> > const xhr = new XMLHttpRequest();
|
||
> > xhr.open('GET', '/api/data');
|
||
> > xhr.send();
|
||
> > // ... 需要时
|
||
> > xhr.abort(); // 终止请求
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q8 — Git 提交前缀 ❌ 答 C(实际正确,待核实)
|
||
|
||
> [!note] `perf` 表示性能优化的修复。常用前缀:feat(新功能)、fix(bug 修复)、perf(性能优化)、refactor(重构)、docs(文档)、test(测试)。
|
||
|
||
---
|
||
|
||
#### Q15 — AJAX 核心对象(重复题)❌ 答 C(实际正确,待核实)
|
||
|
||
> [!note] 与 Q5 完全相同的题目,考察 XMLHttpRequest 全称。
|
||
|
||
---
|
||
|
||
#### Q18 — readyState === 3 ❌ 答 B(实际正确,待核实)
|
||
|
||
> [!note] `readyState` 四个状态值:0 未初始化、1 已打开、2 已发送、**3 交互中(接收响应中)**、4 完成。3 表示正在接收服务器响应数据,但尚未完成。
|
||
|
||
---
|
||
|
||
#### Q20 — CSS 选择器优先级 ❌ 答 D,正确 A
|
||
|
||
> **题目**:哪种写法或选择器优先级最高?
|
||
>
|
||
> > [!answer] `inline style`(行间样式)优先级高于 id、class、标签选择器。
|
||
> >
|
||
> > 优先级排序(从小到大):
|
||
> > `标签选择器 < ID 选择器 < Class 选择器 < 内联样式 < !important`
|
||
>
|
||
> ```css
|
||
> div.box #myId { /* 101 */ }
|
||
> .box { /* 10 */ }
|
||
> div { /* 1 */ }
|
||
> style="color:red" {/* 1000 —— 内联样式优先 */}
|
||
> ```
|
||
|
||
---
|
||
|
||
#### Q21 — apply vs call ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] apply 接收参数数组,call 接收逐个参数。
|
||
|
||
---
|
||
|
||
#### Q22 — 比较运算符 ❌ 答 C,正确 A
|
||
|
||
> **题目**:`2 == '2'` 的结果?
|
||
>
|
||
> > [!answer] `==` 会做类型转换再比较:`Number('2') === 2` → `true`。
|
||
> > `===` 不做类型转换:`2 !== '2'`(number ≠ string)→ `false`。
|
||
> >
|
||
> > 完整输出:`false, true, true, true, false`
|
||
|
||
---
|
||
|
||
#### Q25 — 函数返回值 ❌ 答 C(实际正确,待核实)
|
||
|
||
> [!note] return 后的语句不再执行,但函数可以不写 return(此时返回 undefined),break 只能在循环/switch 中使用。
|
||
|
||
---
|
||
|
||
#### Q26 — 选择第一个类名为 box 的元素 ❌ 答 C(实际正确,待核实)
|
||
|
||
> [!note] `querySelector('.box')` 用 CSS 选择器语法,点号 `.` 表示类名。
|
||
|
||
---
|
||
|
||
#### Q39 — 跨域 HTTP 头部 ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] `Access-Control-Allow-Origin: *` 是 CORS 核心响应头。
|
||
|
||
---
|
||
|
||
#### Q42 — computed 创建计算属性 ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] Vue 的 computed 用于创建缓存的计算属性。
|
||
|
||
---
|
||
|
||
#### Q45 — provide/inject 用途 ❌ 答 D,正确 B
|
||
|
||
> **题目**:provide 和 inject 用于什么?
|
||
>
|
||
> > [!answer] 跨组件通信(包括跨层级父子/兄弟/隔代组件)。它们在祖先组件 provide 数据,后代组件 inject 获取,无需逐级传递 props。注意 B 中"事件总线"表述不准确,更准确说是"依赖注入式跨组件通信"。
|
||
|
||
---
|
||
|
||
#### Q46 — v-bind 指令 ❌ 答 D,正确 A
|
||
|
||
> [!note] `v-bind` 用于动态绑定元素属性,简写为 `:`。
|
||
|
||
---
|
||
|
||
#### Q47 — Whistle 启动命令 ❌ 答 C(实际正确,待核实)
|
||
|
||
> [!note] Whistle 代理工具启动命令:`w2 start`。
|
||
|
||
---
|
||
|
||
#### Q48 — npm 包存放目录 ❌ 答 C(实际正确,待核实)
|
||
|
||
> [!note] NPM 安装的包存放在 `node_modules/` 目录下。
|
||
|
||
---
|
||
|
||
#### Q50 — FormData.append ❌ 答 C,正确 A
|
||
|
||
> **题目**:FormData 中添加键值对的方法?
|
||
>
|
||
> > [!answer] `formData.append(key, value)`。这是 FormData 对象的唯一添加方法。
|
||
> >
|
||
> > ```js
|
||
> > const fd = new FormData();
|
||
> > fd.append('username', 'alice');
|
||
> > fd.append('avatar', fileInput.files[0]); // 也可以添加 File/Blob
|
||
> >
|
||
> > fetch('/upload', { method: 'POST', body: fd });
|
||
> > // 自动设置 Content-Type 为 multipart/form-data
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q53 — HTTP 404 ❌ 答 B(实际正确,待核实)
|
||
|
||
> [!note] 404 = Not Found,请求的资源不存在。
|
||
|
||
---
|
||
|
||
#### Q54 — Webpack devtool ❌ 答 A,正确 B
|
||
|
||
> **题目**:devtool 配置选项的作用?
|
||
>
|
||
> > [!answer] **源代码映射(Source Map)**。它将打包后的代码映射回原始源代码,方便调试。常用值:`source-map`(完整)、`cheap-module-source-map`(开发快)、`eval`(最快)。
|
||
> >
|
||
> > ```js
|
||
> > // webpack.config.js
|
||
> > module.exports = {
|
||
> > devtool: 'source-map', // 生成独立的 .map 文件
|
||
> > };
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q55 — Webpack externals ❌ 答 D,正确 A
|
||
|
||
> **题目**:externals 配置用于什么?
|
||
>
|
||
> > [!answer] **定义外部依赖**。告诉 Webpack 某些模块不应打包进 bundle,而是从外部(如 CDN)引入。
|
||
> >
|
||
> > ```js
|
||
> > module.exports = {
|
||
> > externals: {
|
||
> > jquery: 'jQuery', // import $ from 'jquery' → 使用 window.jQuery
|
||
> > },
|
||
> > };
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q56 — Webpack 代码分割 ❌ 答 B,正确 A
|
||
|
||
> **题目**:Webpack 如何处理代码分割?
|
||
>
|
||
> > [!answer] 通过 `optimization.splitChunks` 配置。它可以将 node_modules 中的公共代码和大型模块拆分为独立的 chunk 文件,减少首屏加载体积。
|
||
> >
|
||
> > ```js
|
||
> > optimization: {
|
||
> > splitChunks: {
|
||
> > chunks: 'all', // 对所有 chunk 进行拆分
|
||
> > cacheGroups: {
|
||
> > vendors: { test: /[\\/]node_modules[\\/], name: 'vendors' }
|
||
> > }
|
||
> > }
|
||
> > }
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q57 — module.exports ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] 导出模块的公共接口。
|
||
|
||
---
|
||
|
||
#### Q58 — Node.js 定义 ❌ 答 B(实际正确,待核实)
|
||
|
||
> [!note] Node.js 是服务端 JavaScript 运行时环境。
|
||
|
||
---
|
||
|
||
#### Q59 — 文件上传编码类型 ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] `enctype="multipart/form-data"` 是文件上传必需的编码类型。
|
||
|
||
---
|
||
|
||
#### Q60 — NPM 配置文件 ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] `package.json` 管理项目依赖和配置。
|
||
|
||
---
|
||
|
||
#### Q61 — 受控 vs 非受控 ❌ 答 D,正确 A
|
||
|
||
> **题目**:受控组件和非受控组件的区别?
|
||
>
|
||
> > [!answer]
|
||
> > - **受控组件**:表单值由 React state 管理,通过 `value` 属性和 `onChange` 事件控制
|
||
> > - **非受控组件**:表单值由 DOM 自身管理,通过 `useRef` 获取值
|
||
> >
|
||
> > ```jsx
|
||
> > // 受控组件
|
||
> > function ControlledInput() {
|
||
> > const [value, setValue] = useState('');
|
||
> > return <input value={value} onChange={e => setValue(e.target.value)} />;
|
||
> > }
|
||
>
|
||
> > // 非受控组件
|
||
> > function UncontrolledInput() {
|
||
> > const inputRef = useRef(null);
|
||
> > return <input ref={inputRef} defaultValue="" />;
|
||
> > }
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q62 — useState 用途 ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] 定义组件的本地状态。
|
||
|
||
---
|
||
|
||
#### Q63 — ESM 导入重命名 ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] `import { originalName as newName }` 是标准语法。
|
||
|
||
---
|
||
|
||
#### Q64 — ESM 默认导入 ❌ 答 B(实际正确,待核实)
|
||
|
||
> [!note] `import defaultExport from 'module'`。
|
||
|
||
---
|
||
|
||
#### Q65 — Webpack resolve ❌ 答 B,正确 A
|
||
|
||
> **题目**:resolve 配置选项用于什么?
|
||
>
|
||
> > [!answer] **解析模块的路径**。例如配置别名、文件扩展名自动补全等。
|
||
> >
|
||
> > ```js
|
||
> > resolve: {
|
||
> > alias: { '@': path.resolve(__dirname, 'src') },
|
||
> > extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||
> > }
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q66 — Webpack optimization ❌ 答 B,正确 C
|
||
|
||
> **题目**:optimization 配置主要用于什么?
|
||
>
|
||
> > [!answer] **优化打包后的文件**。包括代码压缩、Tree Shaking、Code Splitting 等。
|
||
|
||
---
|
||
|
||
#### Q67 — useEffect 清除副作用 ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] 返回清理函数即可清除副作用。
|
||
|
||
---
|
||
|
||
#### Q69 — useEffect 主要用途 ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] 声明式地处理组件的副作用(数据获取、订阅、DOM 操作等)。
|
||
|
||
---
|
||
|
||
#### Q70 — React.memo 优化 ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] 通过浅比较 props 避免不必要的渲染。
|
||
|
||
---
|
||
|
||
#### Q71 — 状态的不可变性 ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] 状态不能被直接修改,必须创建新值。
|
||
|
||
---
|
||
|
||
#### Q74 — 父传子数据传递 ❌ 答 B(实际正确,待核实)
|
||
|
||
> [!note] props 是 React 中父组件向子组件传递数据的主要方式。
|
||
|
||
---
|
||
|
||
#### Q75 — key 的最佳实践 ❌ 答 B(实际正确,待核实)
|
||
|
||
> [!note] 使用列表项的唯一标识(如数据库 id),不要用 index。
|
||
|
||
---
|
||
|
||
#### Q76 — React 组件定义方式 ❌ 答 B(实际正确,待核实)
|
||
|
||
> [!note] 函数组件和类组件都可以。
|
||
|
||
---
|
||
|
||
#### Q77 — useCallback 作用 ❌ 答 B,正确 A
|
||
|
||
> **题目**:useCallback 的主要作用?
|
||
>
|
||
> > [!answer] **缓存函数引用**,避免因每次渲染产生新函数引用而导致子组件(React.memo 包裹的)不必要的重渲染。
|
||
> >
|
||
> > ```jsx
|
||
> > const memoizedFn = useCallback(() => {
|
||
> > doSomething(a, b);
|
||
> > }, [a, b]); // a 或 b 变化时才创建新函数
|
||
> > ```
|
||
|
||
---
|
||
|
||
#### Q83 — React Context 错误说法 ❌ 答 D(实际正确,待核实)
|
||
|
||
> [!note] Context 可以与类组件配合使用(通过 Consumer 或 contextType)。
|
||
|
||
---
|
||
|
||
#### Q84 — 触发重渲染的因素 ❌ 答 D,正确 A
|
||
|
||
> **题目**:哪项会触发组件的重渲染?
|
||
>
|
||
> > [!answer]
|
||
> > - **A 正确**:父组件状态变化会触发父组件及所有子组件重渲染(无论 props 是否变化)
|
||
> > - B 不会:React.memo 且 props 未变化 → 跳过渲染
|
||
> > - C 不会:setState 传入相同值 → React 内部跳过
|
||
> > - D 不会:useRef 变化 → 不触发重渲染(ref 是可变的但不引起渲染)
|
||
|
||
---
|
||
|
||
#### Q85 — React.memo 的正确场景 ❌ 答 D,正确 B
|
||
|
||
> **题目**:使用 React.memo 的正确场景?
|
||
>
|
||
> > [!answer] **避免函数组件因 props 变化导致的不必要重渲染**。适用于 props 稳定、渲染开销大的场景。不适用于类组件,也不替代 useCallback。
|
||
|
||
---
|
||
|
||
#### Q87 — children props 目的 ❌ 答 C(实际正确,待核实)
|
||
|
||
> [!note] 向子组件传递可渲染内容。
|
||
|
||
---
|
||
|
||
#### Q88 — Redux 适用场景 ❌ 答 A(实际正确,待核实)
|
||
|
||
> [!note] 多个不相关组件共享复杂状态。
|
||
|
||
---
|
||
|
||
#### Q89 — 兄弟组件通信 ❌ 答 B(实际正确,待核实)
|
||
|
||
> [!note] 通过共同的父组件中转数据(状态提升)。
|
||
|
||
---
|
||
|
||
#### Q93 — React 性能优化手段 ❌ 答 C(实际正确,待核实)
|
||
|
||
> [!note] useMemo 缓存计算结果 + useCallback 缓存函数引用,两者都是性能优化手段。
|
||
|
||
---
|
||
|
||
#### Q94 — useEffect([]) 等价生命周期 ❌ 答 D,正确 A
|
||
|
||
> **题目**:useEffect 依赖为 `[]` 相当于哪个生命周期?
|
||
>
|
||
> > [!answer] `componentDidMount`。空数组意味着只在组件挂载后执行一次。
|
||
|
||
---
|
||
|
||
#### Q97 — React 单项数据流 ❌ 答 B(实际正确,待核实)
|
||
|
||
> [!note] 数据只能从父流向子,子不能直接改父的数据。
|
||
|
||
---
|
||
|
||
#### Q98 — 浏览器原生模块系统 ❌ 答 B(实际正确,待核实)
|
||
|
||
> [!note] ESM 是浏览器原生支持的模块化方案(`<script type="module">`)。
|
||
|
||
---
|
||
|
||
#### Q104 — LLM 核心原理 ❌ 答 B(实际正确,待核实)
|
||
|
||
> [!note] LLM 对下一个 token 做最大似然预测(Next Token Prediction)。
|
||
|
||
---
|
||
|
||
## 知识点总结
|
||
|
||
### 高频错题知识图谱
|
||
|
||
```mermaid
|
||
mindmap
|
||
root((前端摸考<br/>27 道错题))
|
||
事件处理
|
||
preventDefault vs stopPropagation
|
||
event delegation this vs target
|
||
stopPropagation spelling
|
||
JS核心
|
||
原始类型 vs 引用类型
|
||
传值 vs 传引用
|
||
closure 闭包
|
||
type coercion
|
||
TypeError causes
|
||
异步执行
|
||
Event Loop 优先级
|
||
宏任务 vs 微任务
|
||
var 闭包陷阱
|
||
Vue3
|
||
reactive 解构陷阱
|
||
script setup 自动暴露
|
||
mounted 执行顺序
|
||
provide/inject vs props
|
||
Teleport
|
||
React
|
||
不可变 State
|
||
callback props 子传父
|
||
Fragment 零 DOM
|
||
useEffect 清理时机
|
||
custom Hook 命名规则
|
||
HTTP网络
|
||
4xx 状态码区别
|
||
Content-Type
|
||
CORS header
|
||
构建工具
|
||
Webpack 三大配置
|
||
ESM vs CommonJS
|
||
CSS
|
||
继承性
|
||
getComputedStyle
|
||
选择器优先级
|
||
```
|
||
|
||
---
|
||
|
||
## 关联笔记
|
||
|
||
- [[hhs/REACT/README]]
|
||
- [[hhs/REACT/2. Hooks 篇/05-核心 Hooks]]
|
||
- [[hhs/REACT/2. Hooks 篇/06-性能优化 Hooks]]
|
||
- [[hhs/REACT/2. Hooks 篇/07-自定义 Hooks]]
|
||
- [[hhs/REACT/4. 进阶篇/11-组件通信模式]]
|
||
- [[hhs/REACT/3. 生态工具篇/08-路由管理]]
|