日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

來自1000多個項目的10大JavaScript錯誤淺析

瀏覽:184日期:2023-11-11 10:21:12

作為對社區開發者的回饋,我們從我們的數據庫里選出了10大來自數千個項目的JavaScript錯誤。我們將會給出產生這些錯誤的根源,以及如何避免再發生這些錯誤。如果能夠避免這些錯誤,就可以成為更好的開發者。

數據才是王道,我們通過收集和分析大量數據才選出了這10大JavaScript錯誤。我們收集每一個項目中出現的錯誤,并統計每一個錯誤發生的次數。我們根據錯誤代碼的指紋(fingerprint)對它們進行分組,也就是說,如果第二個錯誤與第一個是重復的,就把它們歸入同一個組。這樣就可以為用戶提供更好的視圖,而不是像查看繁瑣的日志文件那樣。

我們只關注影響面最大的那些錯誤。為此,我們統計了錯誤在各個公司的項目中發生的次數,而不是錯誤發生的總次數,因為如果是這樣的話,讀者就可能看到大量與他們不相干的統計信息。

以下是排名靠前的10大JavaScript錯誤:

來自1000多個項目的10大JavaScript錯誤淺析

出于可讀性方面的考慮,每個錯誤的描述經過精簡。

1.Uncaught TypeError: Cannot read property

如果你是一名JavaScript開發者,對這個錯誤可能已經熟視無睹。在Chrome里讀取未定義對象的屬性或調用未定義對象的方法時就會發生這個錯誤,在Chrome開發者控制臺可以很容易地重現這個錯誤。

來自1000多個項目的10大JavaScript錯誤淺析

發生這個錯誤的原因有很多,其中最為常見的是,在渲染UI組件時沒有正確初始化狀態。我們通過一個真實的例子來看看這個錯誤是怎么發生的。我們選擇React作為示例,不過在其他框架(Angular、Vue等)中也是一樣的。

class Quiz extends Component { componentWillMount() { axios.get(’/thedata’).then(res => { this.setState({items: res.data}); }); } render() { return ( <ul> {this.state.items.map(item => <li key={item.id}>{item.name}</li> )} </ul> ); }}

這里要注意兩件事:

組件的狀態(如this.state)在一開始就是undefined。 如果是通過異步的方式來加載數據,那么在數據加載進來之前,至少要渲染一次組件——不管是在構造器、componentWillMout()還是componentDidMout()中加載數據。Quiz在進行第一次渲染時,this.state.items是undefined,那么ItemList就會得到undefined的數據項,這樣就會在控制臺看到這個錯誤——“Uncaught TypeError:Cannot read property ‘map’ of undefined”。

要解決這個問題其實很簡單,在構造器里使用適當的默認值進行初始化。

class Quiz extends Component { // 增加這個: constructor(props) { super(props); // 使用空數組給state賦值 this.state = { items: [] }; } componentWillMount() { axios.get(’/thedata’).then(res => { this.setState({items: res.data}); }); } render() { return ( <ul> {this.state.items.map(item => <li key={item.id}>{item.name}</li> )} </ul> ); }} 2. TypeError: ’undefined’ is not an object

在Safari里讀取未定義對象的屬性或調用未定義對象的方法時就會發生這個錯誤,在Safari開發者控制臺可以很容易地重現這個錯誤。這個錯誤與發生在Chrome里的是差不多的,只是Safari為它提供了不同的錯誤信息。

來自1000多個項目的10大JavaScript錯誤淺析

3. TypeError: null is not an object

在Safari里讀取空(null)對象的屬性或調用空對象的方法時就會發生這個錯誤,在Safari開發者控制臺可以很容易地重現這個錯誤。

來自1000多個項目的10大JavaScript錯誤淺析

有意思的是,在JavaScript里,null和undefined其實是不一樣的,所以我們會看到兩個不同的錯誤消息。undefined表示未賦值的變量,而null表示變量值為空。可以使用嚴格等于號來證明它們不是同一個東西。

來自1000多個項目的10大JavaScript錯誤淺析

在實際應用當中,在JavaScript里調用一個未加載的DOM元素就會出現這個錯誤。如果對象為空,DOM API就會返回null。

DOM元素需要在創建之后才能被訪問。JavaScript代碼是按照從上到下的順序進行解析的,所以,如果在DOM元素之前有一個標簽包含了JavaScript代碼,瀏覽器在解析HTML時就會執行這些代碼。在加載JavaScript之前,如果DOM元素沒有被創建,就會出現這個錯誤。

在這個例子里,我們可以通過添加一個事件監聽器來解決這個問題,在頁面加載完畢時,事件監聽器會通知我們。在addEventListener被觸發之后,init()方法就可以大膽地訪問DOM元素了。

<script> function init() { var myButton = document.getElementById('myButton'); var myTextfield = document.getElementById('myTextfield'); myButton.onclick = function() { var userName = myTextfield.value; } } document.addEventListener(’readystatechange’, function() { if (document.readyState === 'complete') { init(); } });</script><form> <input type='text' placeholder='Type your name' /> <input type='button' value='Go' /></form> 4. (unknown): Script error

跨域的未捕捉JavaScript異常會變成Script error。例如,假設JavaScript托管在CDN上,那么未捕捉的錯誤(錯誤沒有在try-catch里被捕獲,一路直上到了window.onerror里)就會顯示成“Script error”,而不是顯示具體的錯誤消息。這是瀏覽器出于安全方面的考慮,防止跨域傳遞數據。

要想獲得具體的錯誤信息,可以這樣做:

1).使用Access-Control-Allow-Origin

將Access-Control-Allow-Origin設置成“*”,表示該資源可以被任何一個域訪問。如果有必要,可以把“*”替換成你的域名,例如Access-Control-Allow-Origin: www.example.com。不過,如果使用了CDN,那么要支持多個域名可能就會得不償失,因為CDN存在緩存問題。

下面是在各種環境如何設置該字段的示例:

Apache

在JavaScript文件所在的目錄創建一個叫作.htaccess的文件,并加入如下內容:

Header add Access-Control-Allow-Origin “*'

Nginx

在JavaScript對應的location配置代碼塊中加入add_header指令:

location ~ ^/assets/ { add_header Access-Control-Allow-Origin *;}

HAProxy

在JavaScript文件對應的backend配置塊中加入如下內容:

rspadd Access-Control-Allow-Origin: *

2). 在script標簽里設置crossorigin=“anonymous”

在每個設置了Access-Control-Allow-Origin字段的HTML頁面里,將它們的script標簽的crossorigin屬性設置為“anonymous”。在Firefox里,如果出現了crossorigin,但沒有設置Access-Control-Allow-Origin,JavaScript腳本就不會被執行。

5. TypeError: Object doesn’t support property

在IE里讀取未定義對象的屬性或調用未定義對象的方法時就會發生這個錯誤,在IE開發者控制臺可以很容易地重現這個錯誤。

來自1000多個項目的10大JavaScript錯誤淺析

這個錯誤與Chrome里的“TypeError: ‘undefined’ is not a function”是同一個東西。不同的瀏覽器為相同的錯誤提供的錯誤消息可能是不一樣的。

在IE里使用JavaScript的命名空間時,就很容易碰到這個錯誤。發生這個錯誤十有八九是因為IE無法將當前命名空間里的方法綁定到this關鍵字上。例如,假設有個命名空間Rollbar,它有一個方法叫isAwesome()。在Rollbar命名空間中,可以直接使用this關鍵字來調用這個方法:

this.isAwesome();

在Chrome、Firefox和Opera中這樣做都是沒有問題的,但在IE中就不行。所以,最安全的做法是指定全命名空間:

Rollbar.isAwesome(); 6. TypeError: ‘undefined’ is not a function

在Chrome里調用一個未定義的函數時就會發生這個錯誤,可以在Chrome開發者控制臺和Mozilla開發者控制臺重現這個錯誤。

來自1000多個項目的10大JavaScript錯誤淺析

近年來,JavaScript的編碼技術和設計模式變得日趨復雜,回調和閉包中的自引用情況越來越普遍,讓人搞不清楚代碼中的this/that表示的是什么意思。

比如下面這段代碼:

function testFunction() { this.clearLocalStorage(); this.timer = setTimeout(function() { this.clearBoard(); // 這里的”this'是指什么? }, 0);};

執行上面的代碼會出現這樣的錯誤:“Uncaught TypeError: undefined is not a function”。因為在調用setTimeout()方法時,實際上是在調用window.setTimeout()。傳給setTimeout()的匿名函數的上下文實際上是window,而window并不包含clearBoard()方法。

對于舊瀏覽器,以往的解決辦法是將this賦值給某個變量,然后在閉包里使用這個變量。例如:

function testFunction () { this.clearLocalStorage(); var self = this; // 將this賦值給self this.timer = setTimeout(function(){ self.clearBoard(); }, 0);};

在新瀏覽器中,可以使用bind()方法來傳遞引用:

function testFunction () { this.clearLocalStorage(); this.timer = setTimeout(this.reset.bind(this), 0); // 綁定到 ’this’};function testFunction(){ this.clearBoard(); // 以’this’作為上下文}; 7. Uncaught RangeError: Maximum call stack

在Chrome里,有幾種情況會發生這個錯誤,其中一個就是無限遞歸調用一個函數。這個錯誤可以在Chrome開發者控制臺重現。

來自1000多個項目的10大JavaScript錯誤淺析

當傳給函數的值超出可接受的范圍時也會出現這個錯誤。很多函數只接受指定范圍的數值,例如,Number.toExponential(digits)和Number.toFixed(digits)只接受0到20的數值,而Number.toPrecision(digits)只接受1到21的數值。

var a = new Array(4294967295); //OKvar b = new Array(-1); //range errorvar num = 2.555555;document.writeln(num.toExponential(4)); //OKdocument.writeln(num.toExponential(-2)); //range error!num = 2.9999;document.writeln(num.toFixed(2)); //OKdocument.writeln(num.toFixed(25)); //range error!num = 2.3456;document.writeln(num.toPrecision(1)); //OKdocument.writeln(num.toPrecision(22)); //range error! 8. TypeError: Cannot read property ‘length’

在Chrome里讀取undefined變量的length屬性時會發生這個錯誤,這個錯誤可以在Chrome開發者控制臺重現。

來自1000多個項目的10大JavaScript錯誤淺析

length是數組的屬性,但如果數組沒有初始化或者數組的變量名被另一個上下文隱藏起來的話,訪問length屬性就會發生這個錯誤。例如:

var testArray= ['Test'];function testFunction(testArray) { for (var i = 0; i < testArray.length; i++) { console.log(testArray[i]); }}testFunction();

函數的參數名會覆蓋全局的變量名。也就是說,全局的testArray被函數的參數名覆蓋了,所以在函數體里訪問到的是本地的testArray,但本地并沒有定義testArray,所以出現了這個錯誤。

有兩種方法可用于解決這個問題:

1). 將函數的參數名移除(這就表示函數里要訪問的變量已經在函數外面定義好了,所以函數不需要參數):

var testArray = ['Test'];/* 前提是要在函數外面定義好testArray */function testFunction(/* No params */) { for (var i = 0; i < testArray.length; i++) { console.log(testArray[i]); }}testFunction();

2). 在調用函數時將變量傳遞進去:

var testArray = ['Test'];function testFunction(testArray) { for (var i = 0; i < testArray.length; i++) { console.log(testArray[i]); }}testFunction(testArray); 9. Uncaught TypeError: Cannot set property

我們無法對undefined變量進行賦值或讀取操作,否則的話會拋出“Uncaught TypeError: cannot set property of undefined”異常。

例如,在Chrome中:

來自1000多個項目的10大JavaScript錯誤淺析

如果test對象不存在,就會拋出“Uncaught TypeError: cannot set property of undefined”異常。

10. ReferenceError: event is not defined

在訪問一個未定義的對象或超出當前作用域的對象時就會發生這個錯誤,這個錯誤可以在Chrome開發者控制臺重現。

來自1000多個項目的10大JavaScript錯誤淺析

如果在進行事件處理時遇到這個錯誤,請確保事件對象被作為參數傳入到函數當中。舊瀏覽器(IE)提供了全局的event變量,但并不是所有的瀏覽器都會這樣。盡管jQuery嘗試對這種行為進行規范化,但最好還是使用傳給函數的event對象:

function myFunction(event) { event = event.which || event.keyCode; if(event.keyCode===13){ alert(event.keyCode); }} 結論

我們希望這些內容能夠幫助大家在未來避免這些錯誤,解決大家的痛點。不過,即使有了這些最佳實踐,在生產環境中仍然會出現各種不可預期的錯誤。關鍵是要及時發現那些影響用戶體驗的錯誤,并使用適當的工具快速解決這些問題。

查看英文原文: Top 10 JavaScript errors from 1000+ projects (and how to avoid them)

感謝徐川對本文的審校。

來自:http://www.infoq.com/cn/articles/top-10-javascript-errors

標簽: JavaScript
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
美女视频一区在线观看| 久久国产精品色av免费看| 欧美a级一区二区| 国产精品欧美日韩一区| 国产精品nxnn| 国产一区二区三区91| 色爱综合网欧美| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 日韩有码av| 亚洲精品乱码日韩| 91av一区| 精品国产乱码久久久久久1区2匹| 成人在线视频中文字幕| 日韩在线不卡| 蜜桃成人av| 伊人精品久久| 亚洲欧洲午夜| 精品国产乱码久久久| www.com.cn成人| 老色鬼精品视频在线观看播放| 亚洲一区成人| 欧美日韩午夜| 精品资源在线| 亚洲天堂久久| 国产精品调教| 欧美丰满日韩| 欧美天堂视频| 欧美日韩一区二区高清| 免费在线欧美黄色| 国产一区观看| 精品三级久久久| 97久久亚洲| 成人午夜网址| 欧美日韩18| 国产精品人人爽人人做我的可爱| 国产精品久久久久77777丨| 99国产精品私拍| 久久亚洲国产精品尤物| 日韩激情一二三区| 宅男噜噜噜66国产日韩在线观看| 国产精品视频一区二区三区| 日本不卡的三区四区五区| 蜜桃av一区二区三区电影| 国内亚洲精品| 91精品一区国产高清在线gif| 7777精品| 丝袜亚洲另类欧美| 国产suv精品一区二区四区视频| 久久婷婷国产| 黄色成人在线网址| 在线精品一区| 成午夜精品一区二区三区软件| 久久人人88| 日本不卡免费高清视频在线| 久草精品视频| 精品色999| 日韩不卡免费高清视频| 日本免费一区二区三区四区| 激情视频网站在线播放色| 在线天堂资源www在线污| 精品一区91| 欧美日韩免费观看一区=区三区| 精品伊人久久久| 麻豆网站免费在线观看| 激情综合在线| 红桃视频国产一区| 综合精品一区| 麻豆精品在线视频| 精品72久久久久中文字幕| 国产美女久久| 欧洲亚洲一区二区三区| 97欧美在线视频| 久久久国产精品网站| 亚洲精品黄色| 国产成人免费视频网站视频社区| 国产精品日韩精品在线播放| 欧美激情另类| 高清日韩中文字幕| 欧美1区2区3区| 日韩精品欧美大片| 色爱av综合网| 青青草伊人久久| 日韩黄色大片| 丝袜亚洲另类欧美| 久久精品高清| 国产精品手机在线播放| 久久精品青草| 国产日韩专区| 红杏一区二区三区| 日韩福利视频网| 久久久久免费av| 国产欧美日韩精品高清二区综合区| 国产日韩欧美一区| 亚洲va在线| 久久不见久久见免费视频7| 久久国产精品色av免费看| 久久夜夜操妹子| 亚洲精品888| 亚洲精品乱码| 免费看av不卡| 亚洲一二三区视频| 久久夜夜操妹子| 久久不卡国产精品一区二区| 欧美成人久久| 国产videos久久| 久久精品一区二区三区中文字幕| 精品亚洲美女网站| 久久精品卡一| 久久99国产精品视频| 亚洲三级av| 久久久久久黄| 亚洲毛片视频| **爰片久久毛片| 国产亚洲精品精品国产亚洲综合| 日韩一级不卡| 岛国av在线播放| 高清一区二区三区| 久久久久久婷| 日韩欧美高清一区二区三区| 一本大道色婷婷在线| 久久99影视| 91精品福利观看| 美女高潮久久久| 国产精品红桃| 国产欧美丝祙| 国产va免费精品观看精品视频| 免费一级欧美片在线观看网站| 久久的色偷偷| 电影91久久久| 91成人精品| 日韩av三区| 久久精品亚洲| 日韩成人午夜精品| 波多视频一区| 久久亚洲图片| 国产精品v一区二区三区| 四季av一区二区凹凸精品| 私拍精品福利视频在线一区| 欧美日韩国产v| 视频在线在亚洲| 在线视频免费在线观看一区二区| 亚洲经典在线| 欧美中文字幕| 亚洲一区免费| 在线亚洲欧美| 日韩中文影院| 老司机精品视频网| 在线亚洲精品| 成人羞羞在线观看网站| 日韩一级网站| 日韩av一级片| 日韩高清成人| 一区二区视频欧美| 日本精品另类| 国产一区清纯| 国产一区二区三区四区五区| 伊人久久成人| 高清精品久久| 国产乱论精品| 蜜芽一区二区三区| 国产综合亚洲精品一区二| 国产精品视频一区二区三区四蜜臂 | 亚洲精品护士| 国产欧美自拍一区| 国产精品对白久久久久粗| 欧美日韩一二三四| 欧美一区自拍| 美女在线视频一区| 欧美a级片一区| 视频精品一区二区| 国产美女高潮在线观看| 鲁大师成人一区二区三区| 麻豆精品视频在线观看| 在线成人直播| 婷婷激情久久| 最新日韩av| 久久精品伊人| 天海翼精品一区二区三区| 午夜欧美理论片| 美女性感视频久久| 国产高清一区| 99久久夜色精品国产亚洲狼 | 桃色一区二区| 亚州av日韩av| 国产精品丝袜xxxxxxx| 欧美xxxx中国| 欧产日产国产精品视频| 成人一区而且| 麻豆mv在线观看| 亚洲精华国产欧美| 久久99免费视频| 日本午夜精品久久久| 综合激情视频| 欧美一区影院| 国产成人精品福利| 蜜桃av在线播放| 久久亚洲风情| 欧美极品中文字幕| 亚洲国产综合在线看不卡| 亚洲欧美日本国产|