一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

10 個(gè)最常見(jiàn)的 JavaScript 錯(cuò)誤(以及如何避免它們)- 來(lái)自 Rollbar 1000 ...

 板橋胡同37號(hào) 2020-01-29

為了回饋我們的開(kāi)發(fā)者社區(qū),我們查看了數(shù)千個(gè)項(xiàng)目的數(shù)據(jù)庫(kù),發(fā)現(xiàn)了 JavaScript 的 10 大錯(cuò)誤。我們將向你展示這些錯(cuò)誤的原因,以及如何防止這些錯(cuò)誤發(fā)生。如果你避免了這些 “陷阱” ,這將使你成為一個(gè)更好的開(kāi)發(fā)人員。
由于數(shù)據(jù)是國(guó)王,我們收集,分析并排名前十的 JavaScript 錯(cuò)誤。 Rollbar 會(huì)收集每個(gè)項(xiàng)目的所有錯(cuò)誤,并總結(jié)每個(gè)項(xiàng)目發(fā)生的次數(shù)。 我們根據(jù) 指紋 對(duì)錯(cuò)誤進(jìn)行分組,來(lái)做到這一點(diǎn)。基本上,如果第二個(gè)錯(cuò)誤只是第一個(gè)錯(cuò)誤的重復(fù),我們會(huì)把兩個(gè)錯(cuò)誤分到同一組。 這給用戶(hù)一個(gè)很好的概括,而不是像在日志文件中看到的那些壓迫性的一大堆垃圾描述。
我們專(zhuān)注于最有可能影響你和你的用戶(hù)的錯(cuò)誤。 為此,我們通過(guò)橫跨不同公司的項(xiàng)目數(shù)來(lái)排列錯(cuò)誤。 如果我們只查看每個(gè)錯(cuò)誤發(fā)生的總次數(shù),那么大流量的項(xiàng)目可能會(huì)淹沒(méi)與大多數(shù)讀者無(wú)關(guān)的錯(cuò)誤的數(shù)據(jù)集。
以下是排名前 10 的 JavaScript 錯(cuò)誤:

為了便于閱讀,沒(méi)有花大段的文字來(lái)描述每個(gè)錯(cuò)誤。讓我們深入到每一個(gè)錯(cuò)誤,來(lái)確定什么可以導(dǎo)致它,以及如何避免它發(fā)生。

1.Uncaught TypeError: Cannot read property

如果你是一個(gè) JavaScript 開(kāi)發(fā)人員,你可能已經(jīng)看到這個(gè)錯(cuò)誤的次數(shù)比你敢承認(rèn)的要多。當(dāng)你讀取一個(gè)屬性或調(diào)用一個(gè)未定義的對(duì)象的方法時(shí),這個(gè)錯(cuò)誤會(huì)在 Chrome 中發(fā)生。你可以在 Chrome 開(kāi)發(fā)者工具的控制臺(tái)中輕松測(cè)試。

發(fā)生這種情況的原因很多,但常見(jiàn)的一種情況是在渲染UI組件時(shí)不恰當(dāng)?shù)爻跏蓟?state(狀態(tài))。 我們來(lái)看一個(gè)在真實(shí)應(yīng)用程序中如何發(fā)生的例子。 我們將選擇 React,但不正確初始化的原則也適用于Angular,Vue或任何其他框架。
JavaScript 代碼:
  1. classQuizextendsComponent{

  2. componentWillMount() {

  3. axios.get('/thedata').then(res => {

  4. this.setState({items: res.data});

  5. });

  6. }

  7. render() {

  8. return(

  9. <ul>

  10. {this.state.items.map(item =>

  11. <li key={item.id}>{item.name}</li>

  12. )}

  13. </ul>

  14. );

  15. }

  16. }

這里有兩件重要的事情要實(shí)現(xiàn):
  1. 組件的狀態(tài)(例如 this.state)從 undefined 開(kāi)始。

  2. 當(dāng)您異步獲取數(shù)據(jù)時(shí),組件在數(shù)據(jù)加載之前至少會(huì)渲染一次,而不管它是在構(gòu)造函數(shù) componentWillMount 還是 componentDidMount 中獲取的。 當(dāng) Quiz 第一次渲染時(shí),this.state.items 是 undefined。 這又意味著 ItemList 將 items 定義為 undefined ,并且在控制臺(tái)中出現(xiàn)錯(cuò)誤 – “Uncaught TypeError: Cannot read property ‘map’ of undefined”。

這個(gè)問(wèn)題很容易解決。最簡(jiǎn)單的方法:在構(gòu)造函數(shù)中用合理的默認(rèn)值來(lái)初始化 state。
JavaScript 代碼:
  1. classQuizextendsComponent{

  2. // 添加這些代碼:

  3. constructor(props) {

  4. super(props);

  5. // 分配 state(狀態(tài)) 本身,以及 items 的默認(rèn)值

  6. this.state = {

  7. items: []

  8. };

  9. }

  10. componentWillMount() {

  11. axios.get('/thedata').then(res => {

  12. this.setState({items: res.data});

  13. });

  14. }

  15. render() {

  16. return(

  17. <ul>

  18. {this.state.items.map(item =>

  19. <li key={item.id}>{item.name}</li>

  20. )}

  21. </ul>

  22. );

  23. }

  24. }

你的應(yīng)用中的確切代碼可能會(huì)有所不同,但是我們希望我們已經(jīng)給了你足夠的線索,來(lái)解決或避免在你的應(yīng)用程序中出現(xiàn)這個(gè)問(wèn)題。如果你還沒(méi)有碰到,請(qǐng)繼續(xù)閱讀,因?yàn)槲覀儗⒃谙旅娓采w更多相關(guān)錯(cuò)誤的示例。

2.TypeError: ‘undefined’ is not an object (evaluating

這是在 Safari 中讀取屬性或調(diào)用未定義對(duì)象上的方法時(shí)發(fā)生的錯(cuò)誤。你可以在 Safari Developer Console 中輕松測(cè)試。這與 Chrome 的上述錯(cuò)誤基本相同,但 Safari 使用不同的錯(cuò)誤消息。

3.TypeError: null is not an object (evaluating

這是在Safari中讀取屬性或調(diào)用 空對(duì)象(null) 上的方法時(shí)發(fā)生的錯(cuò)誤。您可以在 Safari Developer Console中輕松測(cè)試。

有趣的是,在 JavaScript 中,null 和 undefined 是不一樣的,這就是為什么我們看到兩個(gè)不同的錯(cuò)誤信息。 undefined 通常是一個(gè)尚未分配的變量,而 null 表示該值為空。 要驗(yàn)證它們不相等,請(qǐng)嘗試使用嚴(yán)格相等運(yùn)算符 === :

在現(xiàn)實(shí)的例子中,這種錯(cuò)誤可能發(fā)生的一種場(chǎng)景是:如果在加載元素之前嘗試在 JavaScript 中使用 DOM 元素。這是因?yàn)?DOM API 對(duì)于空白的對(duì)象引用返回 null 。
任何執(zhí)行和處理 DOM 元素的 JS 代碼都應(yīng)在 DOM 元素創(chuàng)建后執(zhí)行。JS 代碼按照 HTML 中的規(guī)定從上到下進(jìn)行解析。所以,如果 DOM 元素之前有一個(gè) script 標(biāo)簽, script 標(biāo)簽內(nèi)的JS代碼將在瀏覽器解析 HTML 頁(yè)面時(shí)執(zhí)行。如果在加載腳本之前尚未創(chuàng)建 DOM 元素,則會(huì)出現(xiàn)此錯(cuò)誤。
在這個(gè)例子中,我們可以通過(guò)添加一個(gè)事件監(jiān)聽(tīng)器來(lái)解決這個(gè)問(wèn)題,這個(gè)監(jiān)聽(tīng)器會(huì)在頁(yè)面準(zhǔn)備好的時(shí)候通知我們。一旦 addEventListener 被觸發(fā),init() 方法就可以使用 DOM 元素。
HTML 代碼:
  1. <script>

  2. function init() {

  3. var myButton = document.getElementById('myButton');

  4. var myTextfield = document.getElementById('myTextfield');

  5. myButton.onclick = function() {

  6. var userName = myTextfield.value;

  7. }

  8. }

  9. document.addEventListener('readystatechange', function() {

  10. if(document.readyState === 'complete') {

  11. init();

  12. }

  13. });

  14. </script>

  15. <form>

  16. <inputtype='text'id='myTextfield'placeholder='Type your name'/>

  17. <inputtype='button'id='myButton'value='Go'/>

  18. </form>

4.(unknown): Script error

當(dāng)一個(gè)未捕獲的 JavaScript 錯(cuò)誤違反了跨域策略時(shí),就會(huì)出現(xiàn)這類(lèi)腳本錯(cuò)誤。例如,如果你將 JavaScript 代碼托管在 CDN 上,任何未被捕獲的錯(cuò)誤(這個(gè)會(huì)冒泡到 window.onerror 處理程序,而不是在 try-catch 捕獲)將被報(bào)告為簡(jiǎn)單的 “腳本錯(cuò)誤” ,而不會(huì)包含有用的信息。這是一種瀏覽器安全措施,旨在防止跨域傳遞數(shù)據(jù),否則將不允許進(jìn)行通信。
如果你要獲取到真實(shí)的錯(cuò)誤消息,請(qǐng)執(zhí)行以下操作:
  1. 發(fā)送 Access-Control-Allow-Origin 頭信息

將 Access-Control-Allow-Origin 頭信息設(shè)置為 * ,表示可以從任何域正確訪問(wèn)資源。如有必要,您可以用你的域名替換 *,例如 Access-Control-Allow-Origin: www.example.com 。但是,處理多個(gè)域名會(huì)有些棘手,如果你使用 CDN ,由此出現(xiàn)的緩存問(wèn)題可能會(huì)讓你感覺(jué)不值得付出努力。 點(diǎn)擊這里 看到更多。
下面是一些如何在不同環(huán)境中設(shè)置 Access-Control-Allow-Origin 頭信息的例子。

Apache

在 JavaScript 文件所在的文件夾中,使用以下內(nèi)容創(chuàng)建一個(gè) .htaccess 文件:
.htaccess 代碼:
  1. HeaderaddAccess-Control-Allow-Origin'*'

Nginx

將 add_header 指令添加到提供 JavaScript 文件的位置塊中:
Nginx 代碼:
  1. location ~ ^/assets/{

  2. add_header Access-Control-Allow-Origin*;

  3. }

HAProxy

將以下內(nèi)容添加到提供資源服務(wù)的后端,并提供 JavaScript 文件:
HAProxy 代碼:
  1. rspadd Access-Control-Allow-Origin:\ *

  1. 在 script 標(biāo)簽上設(shè)置  屬性

在你的 HTML 源代碼中,對(duì)于你設(shè)置的 Access-Control-Allow-Origin 頭信息的每個(gè)腳本,在 script 標(biāo)簽上設(shè)置  。在添加腳本標(biāo)記上的 crossorigin 屬性之前,請(qǐng)確保驗(yàn)證上述頭信息是否正確發(fā)送。在 Firefox 中,如果存在 crossorigin 屬性,但 Access-Control-Allow-Origin 頭信息不存在,則腳本將不會(huì)執(zhí)行。

5.TypeError: Object doesn’t support property

這是你在調(diào)用未定義方法時(shí)發(fā)生在IE中的錯(cuò)誤。你可以在IE開(kāi)發(fā)者工具的控制臺(tái)進(jìn)行測(cè)試。

這相當(dāng)于 Chrome 中的錯(cuò)誤:”TypeError: ‘undefined’ is not a function” 。是的,對(duì)于相同的邏輯錯(cuò)誤,不同的瀏覽器可能會(huì)有不同的錯(cuò)誤消息。
在使用 JavaScript 命名空間的Web應(yīng)用程序中,這中錯(cuò)誤對(duì)于 IE 來(lái)說(shuō)是一個(gè)常見(jiàn)問(wèn)題。在這種情況下,這種問(wèn)題 99.9% 是 IE 無(wú)法將當(dāng)前名稱(chēng)空間內(nèi)的方法綁定到 this 關(guān)鍵字。例如,如果你的 JS 命名空間 Rollbar 中有 isAwesome 方法。通常,如果你在 Rollbar 命名空間內(nèi),則可以使用以下語(yǔ)法調(diào)用 isAwesome 方法:
JavaScript 代碼:
  1. this.isAwesome();

Chrome,F(xiàn)irefox 和 Opera 會(huì)欣然地接受這個(gè)語(yǔ)法。 IE 則不會(huì)。 因此,使用 JS 命名空間時(shí)最安全的選擇是始終以實(shí)際命名空間作為前綴。
JavaScript 代碼:
  1. Rollbar.isAwesome();

6.TypeError: ‘undefined’ is not a function

當(dāng)你調(diào)用未定義的函數(shù)時(shí),在 Chrome 中會(huì)發(fā)生這種錯(cuò)誤。 你可以在 Chrome 開(kāi)發(fā)者工具的控制臺(tái)和 Mozilla Firefox 開(kāi)發(fā)者工具的控制臺(tái)中對(duì)此進(jìn)行測(cè)試。

隨著 JavaScript 編碼技術(shù)和設(shè)計(jì)模式在這些年來(lái)越來(lái)越復(fù)雜,回調(diào)和閉包內(nèi)的自引用作用域也相應(yīng)增加,這是使用 this/that 混亂的一個(gè)相當(dāng)常見(jiàn)的原因。
考慮這個(gè)示例代碼片段:
JavaScript 代碼:
  1. function clearBoard(){

  2. alert('Cleared');

  3. }

  4. document.addEventListener('click', function(){

  5. this.clearBoard(); // what is “this” ?

  6. });

如果你執(zhí)行上面的代碼然后點(diǎn)擊頁(yè)面,會(huì)導(dǎo)致以下錯(cuò)誤: “Uncaught TypeError: this.clearBoard is not a function”。原因是正在執(zhí)行的匿名函數(shù)在 document 上下文中, 而 clearBoard 定義在 window 中。
一個(gè)傳統(tǒng)的,舊瀏覽器兼容的解決方案是簡(jiǎn)單地將你的 this 保存在一個(gè)變量,然后該變量可以被閉包繼承。 例如:
JavaScript 代碼:
  1. varself=this; // save reference to 'this', while it's still this!

  2. document.addEventListener('click', function(){

  3. self.clearBoard();

  4. });

或者,在較新的瀏覽器中,可以使用 bind() 方法傳遞適當(dāng)?shù)囊茫?/span>
JavaScript 代碼:
  1. document.addEventListener('click',this.clearBoard.bind(this));

7.Uncaught RangeError: Maximum call stack

這是 Chrome 在一些情況下會(huì)發(fā)生的錯(cuò)誤。一個(gè)情況是當(dāng)你調(diào)用一個(gè)不終止的遞歸函數(shù)時(shí)。你可以在Chrome開(kāi)發(fā)者工具的控制臺(tái)中進(jìn)行測(cè)試。

如果你一個(gè)將值傳遞給超出范圍的函數(shù),也可能會(huì)發(fā)生這種情況。許多函數(shù)只接受其輸入值的特定范圍的數(shù)字。
例如,
Number.toExponential(digits) 和 Number.toFixed(digits) 接受0到20之間的數(shù)字,
和 
Number.toPrecision(digits) 接受從1到21的數(shù)字。
此外,如果您將值傳遞給超出范圍的函數(shù),也可能會(huì)發(fā)生這種情況。 許多函數(shù)只接受其輸入值的特定范圍的數(shù)字。 例如:Number.toExponential(digits) 和 Number.toFixed(digits) 接受 0 到 20 的數(shù)字,Number.toPrecision(digits) 接受 1 到 21 的數(shù)字。
JavaScript 代碼:
  1. var a = newArray(4294967295); //OK

  2. var b = newArray(-1); //range error

  3. var num = 2.555555;

  4. document.writeln(num.toExponential(4)); //OK

  5. document.writeln(num.toExponential(-2)); //range error!

  6. num = 2.9999;

  7. document.writeln(num.toFixed(2)); //OK

  8. document.writeln(num.toFixed(25)); //range error!

  9. num = 2.3456;

  10. document.writeln(num.toPrecision(1)); //OK

  11. document.writeln(num.toPrecision(22)); //range error!

8.TypeError: Cannot read property ‘length’

這是 Chrome 中發(fā)生的錯(cuò)誤,因?yàn)樽x取未定義變量的長(zhǎng)度屬性。你可以在Chrome開(kāi)發(fā)者工具的控制臺(tái)中進(jìn)行測(cè)試。

你通常會(huì)在數(shù)組中找到定義的長(zhǎng)度,但是如果數(shù)組未初始化或變量名隱藏在另一個(gè)上下文中,則可能會(huì)遇到此錯(cuò)誤。讓我們用下面的例子來(lái)理解這個(gè)錯(cuò)誤。
JavaScript 代碼:
  1. var testArray= ['Test'];

  2. function testFunction(testArray) {

  3. for(var i = 0; i < testArray.length; i++) {

  4. console.log(testArray[i]);

  5. }

  6. }

  7. testFunction();

當(dāng)你用參數(shù)聲明一個(gè)函數(shù)時(shí),這些參數(shù)變成了本地參數(shù)。這意味著即使你有名稱(chēng)為 testArray 的變量,函數(shù)中具有相同名稱(chēng)的參數(shù)仍將被視為 本地參數(shù)。
你有兩種方法可以解決這個(gè)問(wèn)題:
  1. 刪除函數(shù)聲明語(yǔ)句中的參數(shù)(事實(shí)證明如果你想訪問(wèn)那些在函數(shù)之外聲明的變量,你不需要將其作為你函數(shù)的參數(shù)傳入):

JavaScript 代碼:
  1. var testArray = ['Test'];

  2. /* Precondition: defined testArray outside of a function */

  3. function testFunction(/* No params */) {

  4. for(var i = 0; i < testArray.length; i++) {

  5. console.log(testArray[i]);

  6. }

  7. }

  8. testFunction();

  1. 調(diào)用函數(shù)時(shí),將我們聲明的數(shù)組傳遞給它:

JavaScript 代碼:
  1. var testArray = ['Test'];

  2. function testFunction(testArray) {

  3. for(var i = 0; i < testArray.length; i++) {

  4. console.log(testArray[i]);

  5. }

  6. }

  7. testFunction(testArray);

9.Uncaught TypeError: Cannot set property

當(dāng)我們嘗試訪問(wèn)一個(gè)未定義的變量時(shí),它總是返回 undefined ,我們不能獲取或設(shè)置任何 undefined 的屬性。在這種情況下,應(yīng)用程序?qū)伋?“Uncaught TypeError cannot set property of undefined.” 錯(cuò)誤。
例如,在Chrome瀏覽器中:

如果 test 對(duì)象不存在,錯(cuò)誤將會(huì)拋出 “Uncaught TypeError cannot set property of undefined.” 。

10.ReferenceError: event is not defined

當(dāng)你嘗試訪問(wèn)未定義的變量或超出當(dāng)前作用域的變量時(shí),會(huì)引發(fā)此錯(cuò)誤。你可以在Chrome瀏覽器中輕松測(cè)試。

如果你在使用事件處理時(shí)遇到這種錯(cuò)誤,請(qǐng)確保你使用傳入的事件對(duì)象作為參數(shù)。像IE這樣的老瀏覽器提供了一個(gè)全局變量事件, Chrome 會(huì)自動(dòng)將事件變量附加到處理程序。Firefox 不會(huì)自動(dòng)添加它。像jQuery這樣的庫(kù)試圖規(guī)范化這種行為。不過(guò),最佳實(shí)踐是使用傳遞到事件處理程序函數(shù)的方法。
JavaScript 代碼:
  1. document.addEventListener('mousemove', function(event) {

  2. console.log(event);

  3. })

總結(jié)

事實(shí)證明很多都是一些 null 或 undefined 錯(cuò)誤。如果您使用嚴(yán)格的編譯器選項(xiàng),比如 Typescript 這樣的好的靜態(tài)類(lèi)型檢查系統(tǒng)可以幫助您避免它們。它可以警告你,如果一個(gè)類(lèi)型是預(yù)期的,但尚未定義。
我們希望你學(xué)到了一些新的東西,并且可以避免將來(lái)出現(xiàn)這些錯(cuò)誤,或者本指南幫助你解決了頭痛的問(wèn)題。盡管如此,即使有最佳做法,生產(chǎn)環(huán)境中還是會(huì)出現(xiàn)意想不到的錯(cuò)誤。了解影響用戶(hù)的錯(cuò)誤非常重要,并有很好的工具來(lái)快速解決它們。
Rollbar 為你提供生產(chǎn)環(huán)境 JavaScript 錯(cuò)誤的可視性,并為您提供更多上下文來(lái)快速解決它們。例如,它提供了額外的調(diào)試功能,例如 遙測(cè)功能,可以告訴你用戶(hù)的瀏覽器發(fā)生了什么導(dǎo)致錯(cuò)誤。這可以使在本地開(kāi)發(fā)者工具的控制臺(tái)之外發(fā)現(xiàn)問(wèn)題。你可以在 Rollbar 的 JavaScript 應(yīng)用程序的完整功能列表 中了解更多信息。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多

    国产精品亚洲综合色区韩国| 久久热在线免费视频精品| 久热人妻中文字幕一区二区| 日韩中文字幕免费在线视频| 成年午夜在线免费视频| 亚洲在线观看福利视频| 免费高清欧美一区二区视频| 免费一区二区三区少妇| 久久国产亚洲精品成人| 91人妻人澡人人爽人人精品| 国产自拍欧美日韩在线观看| 高清免费在线不卡视频| 在线观看中文字幕91| 东京热男人的天堂社区| 欧美多人疯狂性战派对| 欧洲精品一区二区三区四区| 久久99午夜福利视频| 亚洲一区二区三区免费的视频| 夜色福利久久精品福利| 色婷婷日本视频在线观看| 富婆又大又白又丰满又紧又硬| 国产日产欧美精品视频| 日本不卡视频在线观看| 成人精品日韩专区在线观看| 亚洲中文字幕乱码亚洲| 在线免费观看一二区视频| 欧美夫妻性生活一区二区| 国产一区二区三区口爆在线| 日本中文在线不卡视频| 有坂深雪中文字幕亚洲中文| 成年人视频日本大香蕉久久| 老司机亚洲精品一区二区| 男女午夜视频在线观看免费| 国产视频在线一区二区| 国内精品伊人久久久av高清| 少妇在线一区二区三区| 亚洲成人精品免费在线观看 | 麻豆国产精品一区二区三区| 高清国产日韩欧美熟女| 五月天婷亚洲天婷综合网| 好吊妞视频免费在线观看|