在日常开发中,我们经常需要根据不同条件创建不同的对象。最直接的方式是在代码中到处使用 new,但这样会带来严重的耦合问题。工厂模式正是为了解决这个问题而生的:它让代码不再直接依赖具体类,而是通过“工厂”来创建对象,从而实现解耦。 工厂模式的核心思想是:不要直接 new,让工厂来创建。通过引入工厂这一中间层,实现客户端代码与具体产品类的解耦,让代码更加灵活、易维护、易扩展。 在前端开发中,它尤其适合用于: HTTP 客户端的创建与配置 表单验证器的统一管理 UI 组件的动态生成 各类策略对象、解析器、适配器的生产与注册 当你发现代码中到处都是 `n...
Q1:什么是单例模式? 单例模式是一种创建型设计模式,它确保一个类在整个应用生命周期中只有一个实例,并提供一个全局访问点来获取该实例。 Q2:单例模式的核心特征是什么? 全局唯一性**:应用中只存在一个实例 延迟实例化(常见但非必须)**:通常第一次使用时才创建 全局访问**:提供静态方法(或模块导出)获取实例 Q3:单例模式通常解决什么问题? 避免重复创建“昂贵对象”(例如:数据库连接池、缓存、配置中心客户端、日志器) 保证共享资源的唯一协调者(例如:全局事件总线、任务调度器、锁/限流器)...
目录 什么是 infer 基础用法:在条件类型中推断类型 常见场景与示例 提取函数返回值类型 提取参数类型 提取 Promise 内的类型 提取数组元素类型 内置工具类型中的应用(ReturnType、Parameters 等) 实战:封装工具类型 UnpackPromise First、Last ElementType 进阶技巧:多层 infer、递归推断 总结与学习建议 1. 什么是 infer infer 是 ...
先说结论:平时开发:使用 type 作为首选;发布工具库时:使用 interface,它允许声明合并和类型扩展,这对于用户使用库在做扩展修改接口时是一个很有用的特性。 interface 注重 结构化类型定义,强调描述对象本身的形状。 type 可为任何类型(包括原始类型、联合类型、元组等)和动态生成属性操作符 keyof、in、infer等,用途更广泛。 继承 interface 通过 extends 关键字实现继承 type 通过交叉类型 & 实现继承 重写 interface 当interface重写时,如果有不同的属性,则会添加;如果是...
在 TypeScript 的类型操作中,keyof 和 in 经常一起出现:keyof 用来“取键”,in 用来“遍历键”(映射类型 / Mapped Types)。组合起来就能实现很多常见高级类型(如 Partial、Required 等)。 1. keyof:取对象键名的联合类型 keyof 操作符接受一个对象类型作为参数,返回该对象属性名组成的字面量联合类型。 type Dog = { name: string; age: number }; type D = keyof Dog; // "name" | "age...
EventSource 建立了从浏览器到服务器的单向持久连接,允许服务器主动向客户端推送事件数据,非常适合单向实时数据流场景。与传统的轮询(Polling)和 WebSocket 相比,EventSource 具有以下核心特性: 单向通信:仅支持服务器向客户端推送数据,适合新闻更新、通知提醒等场景 自动重连:连接断开时会自动尝试重连,无需手动处理断线逻辑 轻量级协议:基于 HTTP/HTTPS,使用简单的文本格式传输,开销低于 WebSocket 原生支持:浏览器内置实现,无需额外库依赖 快速上手示例: `j...
Linums 0. 破冰与自我校准(5 分钟) Q0-1 你用 2 分钟介绍这个项目:解决什么问题?核心亮点是什么? 追问 你认为“最难的 3 件事”分别是什么?为什么? 回答 这是一个“多模型 AI 聊天”应用,核心是“低延迟流式输出 + 可视化推理(thinking)+ 工具调用(web_search / generate_image)+ 语音输入输出 + 会话管理与分享”。 最难的点主要有三类: 1) SSE 增量流 + UI 性能:后端把不同模型供应商的上游流统一成“前端可消费的业务事件”(thinkin...
最近,在为 Linums Chat 编写网页侧边栏 collapse 逻辑时,在交互体感上遇到了一些问题,故写下此总结,避免以后继续踩坑。 首先,本项目的侧边栏组件简略代码如下: export function Sidebar({ children, className }: SidebarProps) { const collapsed = useUIStore((s) => s.sidebarCollapsed) const toggleSidebar = useUIStore((s) => s.toggleSidebar) ret...
flex: 1 的含义与实际运用 flex: 1 是 Flexbox 中 flex-grow、flex-shrink、flex-basis 三个属性的简写,常用于“可伸缩、占满剩余空间”的布局。 通常可理解为等价于: flex-grow: 1; flex-shrink: 1; flex-basis: 0%; 备注:在不同浏览器实现与规范演进中,flex 简写的“省略值”细节容易混淆。工程实践里,你可以把 flex: 1 近似理解为“允许增长、允许收缩、并从 0 的基础尺寸开始参与剩余空间分配”,这也是它常用于等分/自适应布局的原...
💫 引言 AIChat类项目,自24年初以来,众多主流产品如 ChatGPT、DeepSeek、Kimi、豆包 等,已如洪水般浪潮涌入我们的视野中,经过迅速迭代,AIChat能凭借复杂的系统工程结构,在LLM能力的基础上完成对LLM的扩展能力。 众所周知,LLM通过人为准备的数据集进行监督训练,经过训练的LLM,能够将输入的Token转换为预测结果,但LLM本身是无状态的,直接与LLM对话并不能使它产生记忆,因为从本质来说,LLM内部只是一堆经过调教好的神经元。LLM在处理长对话时会失去上下文,尤其是在多轮对话或复杂问题解决中,缺乏有效的上下文跟踪和记忆能力。解决这个办法最简单的方式是...