
前言:
寫代碼的過程中,難免會發(fā)生各種錯(cuò)誤,而發(fā)出去的代碼也可能收到用戶瀏覽器報(bào)回來的各種錯(cuò)誤需要查問題。了解這些報(bào)錯(cuò)發(fā)生的原因以及出現(xiàn)的瀏覽器可以幫助我們更快的找到bug,下面就一起來看看排名前十的JS錯(cuò)誤以及避免的方法吧。
一、 Uncaught TypeError: Cannot read property
這個(gè)錯(cuò)誤是Chrome瀏覽器報(bào)的。在嘗試去讀取一個(gè)undefined變量的屬性或者調(diào)用undefined變量的方法就會報(bào)錯(cuò)。你可以在Chrome瀏覽器中輕易復(fù)現(xiàn)。
避免方法:在取變量的屬性值,要保證這個(gè)變量是定義過的。比如可以這樣寫:
foo && foo.bar
二、 TypeError: ‘undefined’ is not an object (evaluating
這個(gè)報(bào)錯(cuò)的原因跟第一條一樣,只是這個(gè)是safari瀏覽器的報(bào)錯(cuò)。可以在safari瀏覽器中復(fù)現(xiàn)。
三、TypeError: null is not an object (evaluating
這條報(bào)錯(cuò)也是來自safari原因也差不多,只是變量從undefine變成了null。所以就是調(diào)用了null的屬性或者方法就會報(bào)這個(gè)錯(cuò)。
四、(unknown): Script error
這條就厲害了,一般我們的監(jiān)控系統(tǒng)也會收到這種錯(cuò)誤,這類型錯(cuò)誤只報(bào)上來一條Script error沒有給你具體的信息,所以會很難查。
那為什么會報(bào)Script error呢?基于安全考慮,瀏覽器有意隱藏其他域JS文件拋出的具體錯(cuò)誤信息,這樣可以避免敏感信息無意中被惡意腳本捕獲。也就是說,瀏覽器只允許同域名的腳本捕獲具體的錯(cuò)誤信息。這本質(zhì)其是瀏覽器跨域錯(cuò)誤。
比如,當(dāng)網(wǎng)站執(zhí)行了托管在第三方CDN的js文件,而這個(gè)js腳本如果有錯(cuò)誤,就會報(bào)Script error,而不是那些有用的信息。
解決方法:
第一步:加跨域HTTP響應(yīng)頭
Access-Control-Allow-Origin: * // 或者是指定網(wǎng)站www.example.com
第二步: 添加 crossorigin=”anonymous”屬性
<script src="http://another-domain.com/App.js " crossorigin="anonymous"></script>
這相當(dāng)于告訴瀏覽器去請求這個(gè)scipt文件的時(shí)候使用匿名的方式獲取,意味著請求腳本時(shí)沒有潛在的用戶身份信息(如cookies、HTTP 證書等)發(fā)送到服務(wù)端。
這里需要注意:在設(shè)置 crossorigin=”anonymous”屬性之前一定要保證http的響應(yīng)頭已經(jīng)設(shè)置了Access-Control-Allow-Origin:* 即允許跨域。否則,在火狐瀏覽器下,這個(gè)script 標(biāo)簽就不會被執(zhí)行。
五、 TypeError: Object doesn’t support property
這個(gè)錯(cuò)誤會在IE報(bào)的,當(dāng)去調(diào)用一個(gè)沒有被定義的方法時(shí)候就會報(bào)這個(gè)錯(cuò)。
這個(gè)錯(cuò)誤跟chrome的"TypeError: ‘undefined’ is not a function"一樣。只是不同的瀏覽器會報(bào)不同的錯(cuò)誤語而已。
這種錯(cuò)誤一般高發(fā)在使用命名空間的IE上。99.9%是因?yàn)镮E無法解析this所指向的正確的命名空間。比如:
var Person = {
name : "daisy",
getName : function() {
console.log(this.name)
},
print: function() {
this.getName()
}
};
比如在Person的命名空間里,print里可以去調(diào)用this.getName()這個(gè)方法。但是在IE不行,所以得明確的寫明命名空間。
var Person = {
name : "daisy",
getName : function() {
console.log(Person.name)
},
print: function() {
Person.getName()
}
};
(注:由于我手頭沒有window電腦,也懶得去找 = =,所以沒有驗(yàn)證過,按照原文的翻譯我理解是這個(gè)意思,大家有興趣可以驗(yàn)證一下,評論區(qū)告訴我結(jié)論~)
六、TypeError: ‘undefined’ is not a function
這個(gè)就是上面說的原因,Chrome/火狐 調(diào)用了沒有定義的方法導(dǎo)致。不在贅述。
當(dāng)然除了疏忽,沒有人會去直接調(diào)用一個(gè)沒有定義的方法,大多是因?yàn)樵诨卣{(diào)函數(shù)或者是必包中,對this的理解不夠造成的。比如:
function clearBoard(){
alert("Cleared");
}
document.addEventListener("click", function(){
this.clearBoard(); // what is “this” ?
});
在這個(gè)case中,回調(diào)函數(shù)里的this其實(shí)指向的是document,而外層定義的clearBoard命名空間作用域在window中,所以就會報(bào)"Uncaught TypeError: this.clearBoard is not a function".的錯(cuò)誤。
有很多種方法可以解決上面的問題:
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
這個(gè)錯(cuò)誤會在Chrome的很多場景下出現(xiàn)。其中有一種就是使用了遞歸卻沒有使用停止的條件。
八、TypeError: Cannot read property ‘length’
這個(gè)錯(cuò)誤是調(diào)用了undefined的length屬性,發(fā)生在Chrome中。
所以我們在取一個(gè)變量的length時(shí)候,一般都是string或者array,要注意他們是有值的。
九、Uncaught TypeError: Cannot set property
給undefined設(shè)置屬性的時(shí)候會報(bào)錯(cuò)。
十、ReferenceError: event is not defined
訪問一個(gè)沒有定義或者不在當(dāng)前作用域的變量會報(bào)這個(gè)錯(cuò)。
什么時(shí)候容易出這個(gè)錯(cuò)呢?在事件的回調(diào)中,如果要使用event要注意傳入event。
document.addEventListener("mousemove", function (event) {
console.log(event);
})
因?yàn)橛行g覽器不會自動幫你傳,比如火狐,就會報(bào)錯(cuò)。所以最好還是自己傳。
原文鏈接:
Top 10 JAVAScript errors from 1000+ projects (and how to avoid them)?rollbar.com
參考文檔:
Script Error產(chǎn)生的原因及解法?juejin.im






