前端2023年11月20日 13:47
JavaScript 如何使用 setTimeout 模拟实现 setInterval?直接用 `setInterval` 有一个经典问题:如果回调执行时间超过了间隔时间,回调会在事件队列中堆积。用 `setTimeout` 递归模拟能解决这个痛点——每次回调执行完再设置下一次定时器,确保上一次执行完毕才开始下一轮计时。
```javascript
function mySetInterval(fn, delay) {
let timer = null;
function loop() {
fn();
timer = setTimeout(loop, delay);
}
timer = setTimeout(loop, delay);
...前端2023年11月20日 13:46
什么是 MVVM 模式?它是为了解决什么问题?MVVM 是 Model-View-ViewModel 的缩写,是一种将 UI 表现层与业务逻辑层分离的架构模式。三层的职责:
- **Model**:数据与业务逻辑,包括数据模型、API 请求、数据校验等
- **View**:UI 展示层,负责渲染界面和接收用户交互
- **ViewModel**:连接 Model 与 View 的桥梁,通过数据绑定让两者自动同步
MVVM 要解决的核心问题是 **View 与 Model 之间的直接耦合**。在传统 MVC 中,View 可能直接读取 Model 数据,Model 变化后手动通知 View 更新,随着业务增长,Controlle...前端2023年11月21日 10:32
如何实现 JavaScript 的 bind 方法?`bind` 是 JavaScript 中显式绑定 `this` 的三种方式之一,与 `call`、`apply` 不同,`bind` 不会立即执行函数,而是返回一个绑定了 `this` 和预设参数的新函数。面试中考察 `bind` 的实现,重点在于:`this` 绑定、参数柯里化、`new` 调用兼容、原型链维护。
## 最简实现:绑定 this + 预设参数
`bind` 的核心行为只有两件事:绑定 `this` 上下文,预设部分参数。
```javascript
Function.prototype.myBind = function(context, ...args) {
...前端2023年11月20日 23:40
如何删除一个 Cookie 值?前端删除 Cookie 的核心思路是**让浏览器判定它已过期**,浏览器会在下次清理时自动移除。JavaScript 没有原生的 `deleteCookie` API,只能通过 `document.cookie` 重新设置同名 Cookie 来"覆盖"并使其失效。
## 方法一:设置 expires 为过去时间
```javascript
document.cookie = 'key=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';
```
这是最经典的做法,兼容所有浏览器。`expires` 接收一个 HTTP 日期格式的字符串,...前端2023年11月20日 23:41
React 项目中常见的内存泄漏场景有哪些?## 核心场景
React 组件卸载后,与之关联的副作用如果没有同步清除,就会产生内存泄漏。实际项目中主要分四类:
### 异步操作更新已卸载组件的状态
在组件内发起 fetch 请求,组件卸载了请求才回来,此时 `setState` 会触发 React 的 warning(React 18 下已移除该 warning,但逻辑上的泄漏仍然存在)。`setTimeout`/`setInterval` 同理——组件卸载了定时器还在跑,回调里访问了过期的 state 或调用 setState。
```javascript
// 泄漏写法
useEffect(() => {
fetc...前端2023年11月28日 23:10
什么是 Virtual DOM?React 为什么用它替代直接操作 DOM?Virtual DOM 是一棵用 JavaScript 对象描述的 DOM 树。React 状态变化时,先在内存里生成新的虚拟 DOM 树,和旧树做 diff,算出最小变更集,再批量更新真实 DOM。这么做的核心原因是——直接操作真实 DOM 太贵了,一次 `appendChild` 可能触发重排+重绘+合成三层渲染管线。Virtual DOM 把"手动精确定位变更"这件事自动化了:你只管声明 UI 长什么样,React 负责高效地同步到真实 DOM。顺带一提,正因为 UI 描述和渲染层解耦,React Native 才能复用同一套组件模型渲染原生控件。
## 追问
### Virt...前端2023年12月22日 23:45
如何判断 JS 文件是 Node.js 环境还是浏览器环境?看三个层面:模块语法、全局对象、环境 API,基本够用。
**模块语法**是最直观的线索——用了 `require`/`module.exports` 的基本是 Node.js(CommonJS),但这不是充分条件,因为浏览器端打包工具也能处理 CJS。反过来,纯 `import`/`export`(ESM)两边都能跑,不能用来判断。
**全局对象**更可靠:访问 `process`、`__dirname`、`__filename`、`global` 的是 Node.js;访问 `window`、`document`、`navigator`、`localStorage` 的是浏览器。...前端2023年11月22日 22:13
如何在 Vue 中实现事件总线 EventBus?Vue 2 里用一个空 Vue 实例做中央事件通道,组件通过它发事件和听事件:
```javascript
// event-bus.js
import Vue from 'vue';
export const EventBus = new Vue();
```
发送端 `EventBus.$emit`,接收端 `EventBus.$on`,销毁前必须 `EventBus.$off` 解绑——忘了这一步就是内存泄漏。
典型场景:登录弹窗成功后通知导航栏更新头像,两个组件隔了好几层,props 传递不现实,EventBus 几行代码搞定。
Vue 3 移除了 `$on/$off`,...前端2023年11月28日 23:08
CSS display 有哪些值?面试必考的 9 个属性详解CSS display 控制元素在页面上的渲染方式,面试常考的就这几个:
**none** — 元素不渲染、不占空间,从布局树中移除。和 `visibility: hidden` 的关键区别:后者保留空间只隐藏视觉效果。频繁切换显隐优先用 `visibility`,因为只触发重绘不触发回流。
**block** — 独占一行,可设宽高。`<div>`、`<p>`、`<h1>` 默认就是 block。
**inline** — 不换行,宽高由内容撑开,垂直方向的 margin/padding 不生效。`<span>`、`<a>` 默认 inline。
**inline-block*...前端2023年11月28日 23:09
Chrome Network Timing 各阶段怎么优化?一次网络请求在 Chrome 里被拆成 6 个阶段,哪个阶段慢就优化哪个。绝大多数性能问题出在两个地方:TTFB 高(服务端处理慢或链路差)和 Content Download 高(响应体大或没压缩)。抓住这两个,性能问题解决大半。
逐阶段排查思路:
- **Queueing(排队)**:浏览器对同一域名限制并发连接数(HTTP/1.1 最多 6 个),超出的请求排队等。解法:升级 HTTP/2 多路复用,或域名分片把资源分散到 cdn1.example.com、cdn2.example.com 等子域名
- **DNS Lookup**:域名解析耗时,首次访问尤其明显。用 `<li...