throw 会中断执行并触发错误处理机制,console.error 仅打印日志且不中断流程;前者需配套 try/catch,后者适合调试输出。

浏览器控制台里 console.error 和 throw 的区别在哪
直接抛出错误(throw new Error("msg"))会中断当前执行流,触发最近的 catch 块或导致未捕获异常;而 console.error 只是打印红色日志,不中断运行。开发时容易误用前者代替后者来“调试”,结果让本该继续的逻辑提前终止。
常见错误现象:点击按钮后界面卡住,检查发现某处写了 throw new Error("TODO") 却没被 try/catch 包裹。
- 调试阶段优先用
console.error+console.trace()定位调用栈 - 业务逻辑中明确需要中断流程时才用
throw,且必须确保有对应的错误处理路径 -
console.error支持多个参数:console.error("API failed:", err, { url, status });,比字符串拼接更利于排查
用 window.onerror 捕获全局 JS 错误时为什么拿不到详细堆栈
跨域脚本(比如 CDN 上的第三方库)抛出的错误,在 window.onerror 中只能拿到 script error.,这是浏览器的安全限制,不是代码写错了。
解决方法只有两个:一是让所有脚本同源,二是给 标签加 crossorigin 属性,并确保服务端返回了正确的 CORS 头(如 Access-Control-Allow-Origin: *)。
立即学习“Java免费学习笔记(深入)”;
- 加了
crossorigin="anonymous"后,window.onerror才能收到真实错误信息和堆栈 - 注意:如果服务端返回的是
Access-Control-Allow-Origin: null或缺失该 header,仍会降级为script error. - 现代项目建议改用
window.addEventListener("error", handler),它对资源加载错误也更敏感
自定义错误类继承 Error 为什么 instanceof 会失效
ES6 类继承 Error 时,若没手动调用 super(message) 或没重设 this.stack,会导致实例无法被正确识别为 Error 子类,err instanceof MyError 返回 false。
根本原因是 V8(Chrome/Node)等引擎在构造 Error 实例时会特殊处理 stack 属性,子类必须显式保留这一行为。
- 正确写法必须调用
super(message),且推荐用Object.setPrototypeOf(this, MyError.prototype)修复原型链 - 简明可靠写法:
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
Object.setPrototypeOf(this, ValidationError.prototype);
}
} - TypeScript 用户注意:启用
compilerOptions.target: "ES2015"及以上,否则extends Error编译后可能丢失原型链
Chrome DevTools 中断点调试时,debugger 语句为什么有时不生效
最常见原因是代码被压缩(minified),debugger 被移除或所在行被合并;其次是开启了 “Blackboxing”(忽略某些脚本),导致断点被跳过。
另一个隐蔽问题是:在异步回调(如 setTimeout、Promise.then)中插入 debugger,但没打开 DevTools 的 “Async stack traces” 选项,导致无法回溯到原始调用位置。
- 确认是否启用了 source map:检查 Sources 面板左侧是否有可展开的原始文件名(而非
bundle.js) - 禁用 Blackboxing:Settings → Ignore list → 清空或检查正则匹配规则
- 调试 Promise 链时,右键调用栈中的 async 函数 → “Reveal in debugger” 可快速跳转
try/catch)的粒度——太粗会掩盖问题根源,太细则增加维护成本。比起无差别包裹每个函数,更值得花时间梳理哪些操作是“可能失败但可预期”的(如 API 请求、JSON 解析),再针对性加守卫。










