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: *)。
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);
}
}compilerOptions.target: "ES2015" 及以上,否则 extends Error 编译后可能丢失原型链debugger 语句为什么有时不生效最常见原因是代码被压缩(minified),debugger 被移除或所在行被合并;其次是开启了 “Blackboxing”(忽略某些脚本),导致断点被跳过。
另一个隐蔽问题是:在异步回调(如 setTimeout、Promise.then)中插入 debugger,但没打开 DevTools 的 “Async stack traces” 选项,导致无法回溯到原始调用位置。
bundle.js)try/catch)的粒度——太粗会掩盖问题根源,太细则增加维护成本。比起无差别包裹每个函数,更值得花时间梳理哪些操作是“可能失败但可预期”的(如 API 请求、JSON 解析),再针对性加守卫。