今天看到公众号一片文章讲前端js的常见错误及处理方法,感觉很有用,特此加以验证并做记录,也希望让更多的人有所收获
常见的错误类型一般有以下几种:
- RangeError: 主要是出现在数组的下标使用时,下标超出了界限
- ReferenceError: 使用一个没有定义的变量会出现引用类型错误
- SyntaxError:语法错误,比如写代码时少个括号啊,或者该使用逗号的使用了分号
- TypeError: 类型错误,例如获取undefined的属性
下面具体分析一下可能产生错误的几种情形
1、RangeError: Maximum call statck size exceeded
含义:
超出了最大的堆栈大小,
报错原因:
在使用递归的时候,消耗大量的堆栈,导致浏览器抛出错误,因为分给浏览器的内存也是有限的
例子
function pow(x,n) {
return x * pow(x, n - 1)
}
pow(10, 5)
处理办法
使用递归的时候,必须有一个终止的条件,不然就会无限循环,直到用尽调用堆栈抛出错误
function pow(x, n) {
if (n == 1) {
return x
}
return x * pow(x, n - 1)
}
pow(10, 5)
2、ReferenceError: “x” is not defined
含义:
x没有定义
报错原因:
引用了一个没有定义的变量,抛出一个ReferenceError的错误,或者在该作用域内不能访问到的变量
例子
console.log(a); //未定义的变量
fn(); //未定义的函数
function sum() {
let number1 = 20;
let number2 = 30;
return number1 + number2;
}
console.log(number1) //作用域里访问不到该变量
处理办法
使用变量时一定要有声明
提升变量的作用域
let a;
function fn() {};
console.log(a);
fn();
// 错误的作用域
let number1 = 20, number2 = 30;
function sum() {
return number1 + number2;
}
console.log(number1)
3、SyntaxError: Identifier ‘x’ has already been declared
含义:
标识符已申明
报错原因:
某个变量名称已经作为参数出现了,又在使用let再次声明
例子
// let 重复声明
let a = 0;
let a = 2;
// 在函数中参数已经出现,函数里使用let重新声明
function fn(arg) {
let arg = [] // 此处不能再使用let声明
}
4、SyntaxError: Invalid or unexpected token
含义:
捕获无效或意外的标记
报错原因:
代码中有非法的字符或者缺少必要的标识符号,比如减号 ( - ) 与连接符 ( – ) ,或者是英文双引号 ( " ) 与中文双引号 ( “ )。
例子
// 遗漏的字符
let str = 'string;
let colors = ['#000', #333', '#666'];
// 使用特殊字符
let str1 = 'string";
let str2 = 5#5;
// 错配字符(使用中文引号字符)
let str3 = ‘string’;
5、SyntaxError: Unexpected end of input
含义:
意外的终止输入
报错原因:
代码中某些地方的括号或引号不匹配缺失,缺少()、[]、{}等。
例子
// 缺少括号
if(true)
let obj = {id: 1
let arr = [1,2,3
// 缺少结束符号
(function () {
console.log('hello world')
}()
6、TypeError: Cannot read property ‘x’ of undefined
TypeError: Cannot set property ‘x’ of undefined
含义:
无法读取属性‘x’, 无法设置属性 ‘x’
报错原因:
访问或设置未定义(undefined)或null值的属性时会发生这种报错。
例子
// undefined
let a = undefined
a.id // 读取
a.id = 1 // 设置
// null
let b = null
b.id // 读取
b.id = 2 // 设置
null.filter(item=>item)
解决办法
获取属性之前先判断一下
let obj = undefined
console.log(obj&&obj.id)
7、‘x’ is not a constructor
含义:
表示 ‘x’不是构造函数
报错原因:
使用不是构造器的对象或者变量来作为构造器使用。
例子
let Car = 1;
new Car();
new Math();
解决办法
使用正确的构造函数。
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
8、 Invalid regular expression flags
含义:
正则表达式标志无效
报错原因:
在代码中出现了无效的正则表达式的标记。
例子
let reg = /foo/bar;
9、DOMException: Failed to execute ‘open’ on ‘XMLHttpRequest’: Invalid URL
含义:
无效的Url
报错原因:
在使用ajax 请求时url错误,导致请求失败。
例子
function createXHR(url) {
let xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('user=admin');
xhr.onreadystatechange = function () {
}
}
createXHR('http://192.168.10.8080') // 错误url
createXHR('http:/192.168.10:8080/open') // 缺少 /,注:有些游览器会自动补全
处理办法
createXHR('http://192.168.10:8080')
异常调试及捕获
try/catch,Js中处理异常的一种模式,try用于可能会发生错误的代码,catch对错误的处理。
try {
// 可能会导致错误的代码
} catch(error) {
// 错误处理
}
例子
try{
console.log(a)
}catch(error) {
// 打印错误信息
console.log(error) // ReferenceError: a is not defined
}
throw可以用来抛出一个用户自定义的异常,执行被停止
function getUserName(name) {
if(!name) throw new Error('用户名无效');
return name;
}
getUserName()
调试的话可以在代码中加入关键字debugger
, 这样代码执行到这里将会停止,方便调试
let value = 15;
debugger
console.log(value)