条件断点必须先设普通断点再右键编辑,VSCode不支持在空白行或注释行直接添加;表达式须为无副作用的JS语法,作用域限于断点行上下文,且需按Enter确认生效。

条件断点必须先打普通断点再右键编辑
VSCode 不支持在空白行号区直接右键添加条件断点。“Add Conditional Breakpoint”菜单项看似可用,但实际触发失败——它不会注册到调试器,后续任何表达式都无效。你得先单击行号左侧灰色区域打一个实心红点(普通断点),再右键该红点,选 Edit Breakpoint 才能输入条件表达式。
这步绕不过:没基础断点,调试协议(DAP)就不知道该把条件绑定到哪一行。常见误操作包括在注释行、空行或函数声明行设点,此时红点是空心的,悬停提示 Unbound breakpoint,条件编辑根本不会生效。
- 确认红点为实心;空心=未绑定,删掉重打
- TS/JSX 项目中,断点必须落在源码可执行行上(比如
console.log()行),不能落在function foo() {这类声明行 - Python 用户同样适用此流程,但表达式仍用 JS 风格(如
user_id == 123),不是 Python 语法
条件表达式只能写无副作用的纯计算式
你写的表达式会被原样传给运行时(V8、debugpy、xdebug 等)求值,不是在 VS Code 进程里执行。所以任何会产生副作用、依赖环境或需要解析上下文的操作都会静默失败或报 ReferenceError。
例如 i = 5 是赋值语句,不是表达式,断点会永远不触发;console.log("hit") 或 fetch("/api") 直接不支持;/error/.test(msg) 在部分 Node 版本中解析失败,改用 msg.includes("error") 更稳妥。
- ✅ 允许:
count > 100、user && user.id === 123、items.length >= 5 - ❌ 禁止:
console.log(i)、localStorage.getItem("token")、if (x) { ... }、let y = 1 - 字符串比较务必加引号:
status === "done",写成status === done就是在查未定义变量done
变量作用域比你想象中更窄
条件表达式求值发生在断点所在行「即将执行前」,能访问的变量严格受限于当前栈帧的作用域。这不是补全问题,而是调试器真实读不到——哪怕变量名在编辑器里高亮了,也可能在运行时不可见。
常见失效场景:在 for (let i of list) 外设断点却写 i === 5;在 setTimeout(() => { x = 1 }, 100) 外层写 x === 1;或者对可能为 null 的对象直接访问属性,如 user.id === 123 而不加空值检查。
- 用
user?.id === 123或user && user.id === 123防TypeError - 异步回调里的变量,在外层断点中大概率未初始化,别指望能查到
- TS 编译后变量名可能被压缩(如
_a),但条件断点仍要写源码名(如userId),靠 source map 映射——混淆构建后这层映射常失效
修改条件后必须按回车确认
右键断点 → Edit Breakpoint → 输入新表达式,光标离开输入框不保存,点击别处也不生效。必须显式按 Enter 键,否则改动丢失,断点继续用旧条件运行。
这个细节极容易被忽略:你以为改好了,其实还在用上次的 i == 10,而你刚输的是 i == 100。更麻烦的是,VS Code 不提示“未保存”,也不灰掉断点图标,它就静静失效。
- 改完表达式,盯住输入框,按
Enter - 不确定是否生效?打开
Debug Console,手动输入表达式中任一变量名(如user),看是否返回有效值 - 多个条件断点叠加时,每个都要单独确认;VS Code 不批量保存
复杂点在于:断点位置、编译配置(sourceMaps、-g)、运行时环境(Node 版本、debugpy 是否启用)三者必须对齐。少一个环节,条件断点就只是个红点。











