JS 中排名前十的报错如何避免-LMLPHP

前言:

写代码的过程中,难免会发生各种错误,而发出去的代码也可能收到用户浏览器报回来的各种错误需要查问题。了解这些报错发生的原因以及出现的浏览器可以帮助我们更快的找到bug,下面就一起来看看排名前十的JS错误以及避免的方法吧。

一、 Uncaught TypeError: Cannot read property

这个错误是Chrome浏览器报的。在尝试去读取一个undefined变量的属性或者调用undefined变量的方法就会报错。你可以在Chrome浏览器中轻易复现。

JS 中排名前十的报错如何避免-LMLPHP

避免方法:在取变量的属性值,要保证这个变量是定义过的。比如可以这样写:

foo && foo.bar
登录后复制

二、 TypeError: ‘undefined’ is not an object (evaluating

这个报错的原因跟第一条一样,只是这个是safari浏览器的报错。可以在safari浏览器中复现。

JS 中排名前十的报错如何避免-LMLPHP

三、TypeError: null is not an object (evaluating

这条报错也是来自safari原因也差不多,只是变量从undefine变成了null。所以就是调用了null的属性或者方法就会报这个错。

JS 中排名前十的报错如何避免-LMLPHP

四、(unknown): Script error

这条就厉害了,一般我们的监控系统也会收到这种错误,这类型错误只报上来一条Script error没有给你具体的信息,所以会很难查。

那为什么会报Script error呢?基于安全考虑,浏览器有意隐藏其他域JS文件抛出的具体错误信息,这样可以避免敏感信息无意中被恶意脚本捕获。也就是说,浏览器只允许同域名的脚本捕获具体的错误信息。这本质其是浏览器跨域错误。

比如,当网站执行了托管在第三方CDN的js文件,而这个js脚本如果有错误,就会报Script error,而不是那些有用的信息。

解决方法:

第一步:加跨域HTTP响应头

Access-Control-Allow-Origin: * // 或者是指定网站www.example.com
登录后复制

第二步: 添加 crossorigin=”anonymous”属性

<script src="http://another-domain.com/app.js " crossorigin="anonymous"></script>
登录后复制

这相当于告诉浏览器去请求这个scipt文件的时候使用匿名的方式获取,意味着请求脚本时没有潜在的用户身份信息(如cookies、HTTP 证书等)发送到服务端。

这里需要注意:在设置 crossorigin=”anonymous”属性之前一定要保证http的响应头已经设置了Access-Control-Allow-Origin:* 即允许跨域。否则,在火狐浏览器下,这个script 标签就不会被执行。

五、 TypeError: Object doesn’t support property

这个错误会在IE报的,当去调用一个没有被定义的方法时候就会报这个错。

JS 中排名前十的报错如何避免-LMLPHP

这个错误跟chrome的"TypeError: ‘undefined’ is not a function"一样。只是不同的浏览器会报不同的错误语而已。

这种错误一般高发在使用命名空间的IE上。99.9%是因为IE无法解析this所指向的正确的命名空间。比如:

var Person = {
    name : "daisy",
    getName : function() {
        console.log(this.name)
    },
    print: function() {
      this.getName()
    }
};
登录后复制

比如在Person的命名空间里,print里可以去调用this.getName()这个方法。但是在IE不行,所以得明确的写明命名空间。

var Person = {
    name : "daisy",
    getName : function() {
        console.log(Person.name)
    },
    print: function() {
      Person.getName()
    }
};
登录后复制

(注:由于我手头没有window电脑,也懒得去找 = =,所以没有验证过,按照原文的翻译我理解是这个意思,大家有兴趣可以验证一下,评论区告诉我结论~)

六、TypeError: ‘undefined’ is not a function

这个就是上面说的原因,Chrome/火狐 调用了没有定义的方法导致。不在赘述。

当然除了疏忽,没有人会去直接调用一个没有定义的方法,大多是因为在回调函数或者是必包中,对this的理解不够造成的。比如:

function clearBoard(){
  alert("Cleared");
}
document.addEventListener("click", function(){
  this.clearBoard(); // what is “this” ?
});
登录后复制

在这个case中,回调函数里的this其实指向的是document,而外层定义的clearBoard命名空间作用域在window中,所以就会报"Uncaught TypeError: this.clearBoard is not a function".的错误。

有很多种方法可以解决上面的问题:

1、可以将外层的this存下来,这样self指向的还是windows。

var self=this;  // save reference to 'this', while it's still this!
document.addEventListener("click", function(){
  self.clearBoard();
});
登录后复制

2、也可以用bind改变this的指向。

document.addEventListener("click",this.clearBoard.bind(this));
登录后复制

七、 Uncaught RangeError

这个错误会在Chrome的很多场景下出现。其中有一种就是使用了递归却没有使用停止的条件。

JS 中排名前十的报错如何避免-LMLPHP

八、TypeError: Cannot read property ‘length’

这个错误是调用了undefined的length属性,发生在Chrome中。

JS 中排名前十的报错如何避免-LMLPHP

所以我们在取一个变量的length时候,一般都是string或者array,要注意他们是有值的。

九、Uncaught TypeError: Cannot set property

给undefined设置属性的时候会报错。

JS 中排名前十的报错如何避免-LMLPHP

十、ReferenceError: event is not defined

访问一个没有定义或者不在当前作用域的变量会报这个错。

JS 中排名前十的报错如何避免-LMLPHP

什么时候容易出这个错呢?在事件的回调中,如果要使用event要注意传入event。

document.addEventListener("mousemove", function (event) {
  console.log(event);
})
登录后复制

因为有些浏览器不会自动帮你传,比如火狐,就会报错。所以最好还是自己传。


推荐教程:《JS教程

以上就是JS 中排名前十的报错如何避免的详细内容,更多请关注Work网其它相关文章!

09-08 07:15