快速掌握前端开发中的常见错误

3,671 阅读8分钟

前言

winter老师的重学前端在刷第二遍,对比第一遍又有了一些更深的了解,建议有需要的同学可以多看几遍,如果能把大佬讲的知识点都掌握了,距离称为大佬就不远了~,今天我们采用winter老师推荐的一种学习方式,来了解一下现在浏览器中支持的一些Error对象,如果你还在经常在捕获到错误的时候不知道该用哪个类型,总是习惯于去throw new Error('xx')的话,相信本文会帮你对error有更进一层的了解~

定义

首先,我们要知道的关于Error的内容如下:

  1. Error对象是JavaScript的一个内置对象,也就是说所有的js引擎都会默认支持这个对象;
  2. 当我们以函数的形式去使用Error的时候,Error('xx err') 和 new Error('xx err')得到的结果是一样的,所以你大可以省略掉new关键字(注意这跟String,Number等内置对象是不一样的,后者使用new和不使用new的场景返回的类型是不同的~);
  3. 通过Error的构造器可以创建一个错误对象。当运行时错误产生时,Error的实例对象会被抛出;

获取浏览器支持的所有Errors对象

这里以chrome为例,打开chrome,在console中复制下面的代码,然后回车拿到结果

Object.getOwnPropertyNames(window).filter(err => err.endsWith ('Error'))

得到结果如下:

image.png

下面我们分别介绍这些错误类型的详情;

Error

关注指数: 5

  1. Error代表一个js中的错误对象,当运行时候有错误发生,Error的实例对象会被抛出,当然我们也可以利用此对象去构造一些自定义的错误对象。
  2. 参数,从caniuse上可以查到,大部分的浏览器都支持了message 和 filename 和lineno(发生错误的代码行数),所以我们使用的时候可以放心大胆的用~

image.png

image.png

image.png

  1. 通过Error可以扩展JavaScript错误类型,举个例子,定义一个BusinessError如下:
class BusinessError extends Error {
   constructor({message, filename, lineno, ...params}){
    super(message, filename, lineno);
    this.name = 'BusinessError'; // 设置name可以修改抛出错误的name
    // TODO: 假装有代码。。
   }
}
  1. 控制台输入
Object.getOwnPropertyNames(window).filter(err => err.endsWith('Error')).map(el => window[el].prototype.__proto__.constructor)

可以看到输出结果:

image.png

除了第一个,从index 1-6 log出来的原型的构造函数都是Error函数,说明这几个错误类型都是继承自Error,下面分别了解一下这几个错误类型的详细内容。

按照关注指数等级从高(5)到低(0)来排序

ReferenceError

关注指数: 5

ReferenceError,当尝试引用一个未被定义的变量时,将会抛出一个 ReferenceError 相对而言,这个错误类型还是一个比较重要的错误类型,我们都知道js里面有一个关键字叫undefined,但是要搞清楚的是,undefined的真正意义并非“未定义”,更贴切的说应该一个变量被声名了,但是未初始化时候的值是undefined,如果真的去直接使用一个未声名的变量,就会出现 ReferenceError

控制台输入 eeee [一个根本未声名过的变量],直接回车就可以看到报错信息:

image.png

这个错误类型在平时开发过程中还是比较常见的,如果下次在遇到,就找找是不是哪个变量没有声名就直接使用了~

SyntaxError

关注指数:5

SyntaxError, 字面意思语法错误,官方解释是-对象代表尝试解析语法上不合法的代码的错误,我们知道js是一个解释性语言,在正真运行的过程中会按照 词法分析[解析成tokens] => 语法分析[转为ast语法树] => 解释执行的过程,转为ast的过程中,js的引擎会同时校验tokens,当它发现不合规范的tokens或者顺序不正确的token的时候,就会报出SyntaxError这个错误;

控制台输入 []{} 和 1.toFixed() ,回车看报错信息:

image.png

可以看到一半都会带上是解析到哪个token的时候出的问题,所以当我们写了一些不符合js语法规范的代码,开发过程中还是要注意一些基本语法的正确性的。

TypeError

关注指数:5

TypeError,字面意思类型错误,官方解释-对象用来表示值的类型非预期类型时发生的错误,实际的意思其实就是当给了一个错误的参数,或者调用了一个错误的,并不存在的方法的时候,就会出现这个错误,看例子:

image.png

当我们调用了一个不存在方法的时候,就会出现TypeError,所以当我们写代码的时候,一定要注意变量的类型,我们知道xx()会去调用这个方法,但是实际上它并不是一个真正function的时候就会报这个错。

RangeError

关注指数:3

RangeError 表示数值变量或参数超出其有效范围,有一种非常常见的场景:[ERROR] : RangeError: Maximum call stack size exceeded.,想必大家都知道这种情况一般是递归过深或者死循环的时候会出现,还有一种比较常见的是new Array的时候给了错误的参数,如下:

image.png

还有一些特殊的情况会导致这个错误,有兴趣的同学可以去自行了解一下~

URLError

关注指数:1

URLError,是一个比较固定场景下会出现的错误,decodeURI, encodeURI, encodeURIComponent, decodeURIComponent当这几个方法在处理url过程中出现错误导致decode或者encode失败的情况下,就会抛出这个类型的错误,这个场景只要记住看到这个类型,就说明是这几个api的问题就可以了。

image.png

EvalError

关注指数:0

EvalError 代表了一个关于eval函数报错的类型,但是目前大部分场景下已经用不到这个类型了,JavaScript不会再抛出此类型的错误,但是会保持这个类型的兼容性,所以对这个错误类型可以不必给与太多的关系。

Error以外的一些错误类型

以上我们就把所有继承自Error的错误都了解完了,下面我们整理一下剩余的一些错误,虽然不是很常见,但是留个印象,遇到的时候能想起来就可以了。

RTCError

这个就不给关注指数了,这个是在使用rtc(网页即时通讯)技术过程中可能会出现的一个错误类型,它是继承自DOMException这个类型的,所以如果你正在从事相关内容开发的话还是需要关注一下的,而我们平常不涉及到的,我觉得等你用的时候再去关注也是没啥问题的。

OverconstrainedError

这个也不给关注指数,同样是一个特定场景才需要关注的问题,浏览器提供了让开发者向用户获取音频和视频权限的api,通过调用MediaDevices.getUserMedia(param)即可,其中param中可以同配置来决定是要音频的权限(录音)还是视频的权限(摄像头),如果是摄像头,甚至可以配置需要的分辨率等配置,当配置的分辨率用户机器上没有,或者达不到的时候,就会报这个错误类型,如果有需要的小伙伴可以自行去查阅这部分的资料~,我附上mdn的地址

DOMError

关注指数:-1

这个API已经被Deprecated了,不要在关注了~

MediaError

关注指数:4

MediaError,用在基于HTMLMediaElement的标签,比如<video/>和<audio/>标签,当这些媒体资源使用过程中报错就会触发这个错误类型,它包含了2部分,一个是code,代表错误的大概类型,另一个message,表示错误的详细信息,具体的内容,可以查看介绍

webkitSpeechRecognitionError

这个也不给关注指数,这个错误首先是基于一个浏览器的实验特性-语音识别来的,因为是在chrome中所以会有webkit前缀,实际上应该是不带私有前缀的,这个错误会在语音识别本身过程出错的时候被抛出,有需要的小伙伴可以到这里去查看相关的内容

总结

以上,我们就把所有chrome浏览器中支持的错误类型都讲完了,可能在日常开发中需要关注的还是Error以及继承自Error的一些错误,至少要做到错误发生的时候知道是什么问题导致的,也好快速定位相关的问题代码所在,如果你有什么好的想法或者建议,欢迎评论留言~