JavaScript 常见错误与解决方案
JavaScript 开发中常见的错误类型及调试方法,帮助快速定位和解决问题。
常见错误类型一览
| 错误类型 |
错误信息 |
原因 |
| ReferenceError |
xxx is not defined |
使用了未定义的变量 |
| TypeError |
Cannot read property 'xxx' of undefined |
访问 undefined/null 的属性 |
| SyntaxError |
Unexpected token |
语法错误 |
| RangeError |
Invalid array length |
数组长度无效 |
| URIError |
URI malformed |
URI 编码/解码错误 |
| EvalError |
EvalError |
eval() 使用错误 |
1. ReferenceError - 未定义变量
console.log(myVar);
let myVar = 'hello';
console.log(myVar);
function test() {
console.log(x);
let x = 1;
}
test();
function test() {
let x = 1;
console.log(x);
}
2. TypeError - 类型错误
const obj = null;
obj.name;
const arr;
arr[0];
const obj = null;
console.log(obj?.name);
const name = obj && obj.name;
const fn = 'hello';
fn();
if (typeof fn === 'function') {
fn();
}
3. 异步错误处理
fetch('/api/data')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
async function fetchData() {
try {
const res = await fetch('/api/data');
const data = await res.json();
return data;
} catch (err) {
console.error('请求失败:', err);
throw err;
}
}
window.addEventListener('unhandledrejection', function(event) {
console.error('未捕获的 Promise 错误:', event.reason);
});
4. 常见逻辑错误
| 错误类型 |
错误示例 |
正确写法 |
| == 与 === |
if (a == null) |
if (a === null || a === undefined) |
| 数组比较 |
[] === [] |
[].length === [].length |
| 对象比较 |
{} === {} |
JSON.stringify(a) === JSON.stringify(b) |
| 浮点数运算 |
0.1 + 0.2 === 0.3 |
Math.abs(0.1+0.2-0.3) < 0.0001 |
| 循环中的闭包 |
for(var i=0;i<3;i++){setTimeout(()=>console.log(i))} |
for(let i=0;i<3;i++){setTimeout(()=>console.log(i))} |
5. 调试技巧
| 技巧 |
用法 |
| console.error() |
输出错误信息 |
| console.trace() |
打印堆栈跟踪 |
| debugger |
设置断点 |
| try-catch |
捕获异常 |
| Chrome DevTools |
Sources 面板调试 |
try {
const result = JSON.parse(invalidJson);
} catch (e) {
console.error('JSON 解析错误:', e.message);
}
function a() { b(); }
function b() { c(); }
function c() {
console.trace('调用栈');
}
a();
function calculate(a, b) {
debugger;
return a + b;
}
6. 错误边界与监控
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.error('错误边界捕获:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return 出错了;
}
return this.props.children;
}
}
7. 最佳实践
| 实践 |
说明 |
| 使用严格模式 |
'use strict'; 捕获更多错误 |
| 使用 TypeScript |
编译时检查类型错误 |
| 启用 ESLint |
静态代码分析,检测潜在问题 |
| 添加错误监控 |
Sentry、Bugsnag 等工具 |
| 合理使用 try-catch |
只在需要时捕获,不要过度使用 |