Ⅰ Web前端工程師要掌握的JavaScript常見BUG及修復方法
今天小編要跟大家分享的文章是關於Web前端工程師要掌握的JavaScript常見BUG及修復方法。JavaScript看上去是一門十分簡單的語言,然而事實並不如此。它有很多容易被弄錯的細節,一不注意就導致BUG。所以今天小編就為大家分享了10個JavaScript常見的bug及修改方法,來和小編一起看一看吧!
一、錯誤的對this進行引用
在閉包或則回調中,this關鍵字的作用域很容易弄錯。舉個例子:
Game.prototype.restart=function(){
this.clearLocalStorage();
this.timer=setTimeout(function(){
this.clearBoard();//此處this指的是?
},0);
};
如果執行上面的代碼,我們會看到報錯:
UncaughtTypeError:undefinedisnotafunction
出錯的原因在於:當你調用setTimeout函數,你實際上調用的是window.setTimeout()。在setTimeout中傳入的匿名函數是在window這個對象環境下,所以this是指向window,但是window並沒有clearBoard方法。
如何解決呢?定義新的變數引用指向Game對象的this,然後就可以使用啦。
Game.prototype.restart=function(){
this.clearLocalStorage();
varself=this;//將this指向的對象綁定到self
this.timer=setTimeout(function(){
self.clearBoard();
},0);
};
或則使用bind()函數:
Game.prototype.restart=function(){
this.clearLocalStorage();
this.timer=setTimeout(this.reset.bind(this),0);//bindto'this'
};
Game.prototype.reset=function(){
this.clearBoard();//此處this的引用正確
};
二、和塊作用域(blockscope)有關的BUG
在大多數程序語言中,每一個函數塊都有一個獨立的新的作用域,但是在JavaScript中並不是。例如:
for(vari=0;i<10;i++){
/*...*/
}
console.log(i);//會輸出什麼呢?
通常在這種情況下,調用console.log()會輸出undefined或則報錯。不過呢,這里會輸出10。在JavaScript中,即使for循環已經結束,變數i依然存在,並且記錄最後的值。有些開發者會忘記這一點,然後導致許多bug。我們可以使用let而不是for來杜絕這一問題。
三、內存泄漏
你需要監控內存使用量,因為泄露很難避免。內存泄露可能由於引用不存在的對象或則循環引用導致。
·如何避免:關注對象的可訪問性(reachability)。
·可訪問的對象:
§現有的callstack任何位置可以訪問的對象
§全局對象
當一個對象可以通過引用訪問到,那麼會在內存中保存。瀏覽器的垃圾回收器僅僅會把那些不可訪問的對象回收。
四、混淆的相等判斷
JavaScript自動將所有在布爾環境下的變數類型轉換為布爾類型,但是可能導致bug。舉例:
//所有都是true
console.log(false==Ɔ');
console.log(null==undefined);
console.log("
"==0);
console.log(''==0);
//注意:下面兩個也是
if({})//
if([])//
{}和[]都是對象,他們都會被轉換為true。為了防止bug出現,推薦使用===和!==來做比較,因為不會隱式做類型轉換。
五、低效的DOM操作
在JavaScript中,你可以輕松操作DOM(添加、修改和刪除),但是開發者往往很低效地去操作。這會導致bug出現,因為這些操作非常耗費計算資源。為了解決這個問題,推薦使用文檔碎片(Document
Fragment),如果你需要操作多個DOM元素。
六、在for循環中錯誤的定義函數
舉例:
varelements=document.getElementsByTagName('input');
varn=elements.length;//假設我們有10個元素
for(vari=0;i
elements[i].onclick=function(){
console.log("元素編號#"+i);
};
}
如果我們有10個元素,那麼點擊任何一個元素都會顯示「元素編號#10」!因為在onclick被調用的時候,for循環已經結束,因此所有的i都是10。
解法:
varelements=document.getElementsByTagName('input');
varn=elements.length;//假設有10個元素
varmakeHandler=function(num){//outerfunction
returnfunction(){//innerfunction
console.log("元素編號##"+num);
};
};
for(vari=0;i
elements[i].onclick=makeHandler(i+1);
}
makeHandler在for循環執行的時候立即被調用,獲取到當前的值i+1,並且存儲在變數num中。makeHandler返回一個函數使用num變數,該函數被綁定到元素的點擊事件。
七、通過原型錯誤地繼承
開發者如果沒能正確理解繼承的原理,那麼就可能寫出有bug的代碼:
BaseObject=function(name){
if(typeofname!=="undefined"){
this.name=name;
}else{
this.name='default'
}
};
varfirstObj=newBaseObject();
varsecondObj=newBaseObject('unique');
console.log(firstObj.name);//->輸出'default'
console.log(secondObj.name);//->輸出'unique'
但是,如果我們做如下操作:
deletesecondObj.name;
那麼:
console.log(secondObj.name);//->輸出'undefined'
而我們實際上想要的結果是列印默認的name。
BaseObject=function(name){
if(typeofname!=="undefined"){
this.name=name;
}
};
BaseObject.prototype.name='default'
每一個BaseObject都繼承name屬性,並且默認值為default。此時如果secondObj的name屬性被刪除掉,通過原型鏈查找會返回正確的默認值。
varthirdObj=newBaseObject('unique');
console.log(thirdObj.name);//->輸出'unique'
deletethirdObj.name;
console.log(thirdObj.name);//->輸出'default'
八、實例方法中的無效引用
我們來實現一個簡單的構造函數用來創建對象:
varMyObject=function(){}
MyObject.prototype.whoAmI=function(){
console.log(this===window?"window":"MyObj");
};
varobj=newMyObject();
為了使用方便,我們定義變數whoAmI來引用obj.whoAmI:
varwhoAmI=obj.whoAmI;
列印出來看看:
console.log(whoAmI);
控制台會輸出:
function(){
console.log(this===window?"window":"MyObj");
}
現在我們來對比一下兩者調用的區別:
obj.whoAmI();//輸出"MyObj"(和期望一致)
whoAmI();//輸出"window"(竟然輸出了window)
當我們把obj.whoAmI賦值給whoAmI的時候,這個新的變數whoAmI是定義在全局下,因此this指向全局的window,而不是MyObj。如果我們真的要獲取對MyObj的函數的引用,需要在其作用域下。
varMyObject=function(){}
MyObject.prototype.whoAmI=function(){
console.log(this===window?"window":"MyObj");
};
varobj=newMyObject();
obj.w=obj.whoAmI;//任然在obj的作用域
obj.whoAmI();//輸出"MyObj"
obj.w();//輸出"MyObj"
九、settimeout/setlnterval函數第一個參數誤用字元串
如果你將一個字元串作為setTimeout/setTimeInterval,它會被傳給函數構造函數並構建一個新的函數。該操作流程很慢而且低效,並導致bug出現。
varhello=function(){
console.log("hello,fundebug!");
}
setTimeout("hello",1000);
一個好的替代方法就是傳入函數作為參數:
setInterval(logTime,1000);//將logTime函數傳入
setTimeout(function(){//傳入一個匿名函數
logMessage(msgValue);
},1000);
十、未能成功使用strictmode
使用strictmodel會增加很多限制條件來加強安全和防止某些錯誤的出現,如果不使用strict
mode,你就相當於少了一個得力的助手幫你避免錯誤:
·更加容易debug
·避免不小心定義了不該定義的全局變數
·避免this隱式轉換
·避免屬性名字或則參數值的重復使用
·eval()更加安全
·無效地使用delete會自動拋出錯誤
以上就是小編今天為大家分享的關於Web前端工程師要掌握的JavaScript常見BUG及修復方法的文章,希望本篇文章能夠對正在從事web前端工作的小夥伴們有所幫助,想要了解更多web前端相關知識記得關注北大青鳥Linux培訓官網,最後祝願小夥伴們工作順利!
作者:fundebug
原文:#/2017/11/15/top_10_bugs_and_fixing_method/
Ⅱ 前端開發bug如何快速
1,根據報錯信息定位:
(1) Uncaught TypeError: Cannot read property 'attr' of undefined;
此類型為變數或者對象屬性未定義類型。
(2) Uncaught TypeError: a.map is not a function;
a.map不是函數,說明a不是數組,只有數組才有map方法。
(3) Uncaught SyntaxError: Invalid or unexpected token;
這種一般是js的代碼格式錯誤。
2, 排除法
頁面中一共有abcd五個方法,注釋掉d後代碼正常說明d有問題。
3,剝離法
同樣一個方法,在A頁面沒問題,在B頁面有問題,這時候,新建一個剝離這個組件,然後運行,如果沒有異常,就算不是這個組件或者方法的問題,然後逐漸在新頁面中加入可能影響B頁面的條件。
Ⅲ 找到一個bug,通過f12,怎麼判斷bug是前端還是後台的
比較前後約定介面地址、參數、返回欄位頁面渲染等,錯誤、缺失則是前端bug。
若上述正確,則大概率是後台bug。
Ⅳ 前端項目上線出現bug可以打斷點調試嗎
可以 按住F12 進入Sources 找到你需要調試的頁面 在左側點一下 就可以打斷點 如下圖
Ⅳ Web前端工作中常見的div+css錯誤
今天小編要為大家分享的文章是關於Web前端工作中常見的div+css錯誤。熟悉web前端工作的小夥伴都知道,web工作需要我們認真仔細,而且一不小心就會出現問題。今天小編就為大家准備了這篇文章大家一起來看一看在web前端工作中如何檢查和處理常見的div+css錯誤。
1.檢查HTML元素是否拼寫錯誤、是否忘記結束標記
即使是老手也經常會弄錯div的嵌套關系。可以用dreamweaver的驗證功能檢查一下有無錯誤。
2.檢查CSS是否正確
檢查一下有無拼寫錯誤、是否忘記結尾的}或者在}後面存在其他符號等。可以利用CleanCSS來檢查
CSS的拼寫錯誤。CleanCSS本是為CSS減肥的工具,但也能檢查出拼寫錯誤。
3.確定錯誤發生的位置
假如錯誤影響了整體布局,則可以逐個刪除div塊,直到刪除某個div塊後顯示恢復正常,即可確定錯誤發生的位置。
4.利用border屬性確定出錯元素的布局特性
使用float屬性布局一不小心就會出錯。這時為元素添加border屬性確定元素邊界,錯誤原因即水落石出。
5.float元素的父元素不能指定clear屬性
MacIE下假如對float的元素的父元素使用clear屬性,四周的float元素布局就會混亂。這是MacIE的聞名的bug,倘若不知道就會走彎路。
6.float元素務必指定width屬性
很多瀏覽器在顯示未指定width的float元素時會有bug。所以不管float元素的內容如何,一定要為其指定width屬性。
另外指定元素時盡量使用em而不是px做單位。
7.float元素不能指定margin和padding等屬性
IE在顯示指定了margin和padding的float元素時有bug。因此不要對float元素指定margin和padding屬性(可以在
float元素內部嵌套一個div來設置margin和padding)。也可以使用hack方法為IE指定非凡的值。
8.float元素的寬度之和要小於100%
假如float元素的寬度之和正好是100%,某些古老的瀏覽器將不能正常顯示。因此請保證寬度之和小於99%。
9.是否重設了默認的樣式?
某些屬性如margin、padding等,不同瀏覽器會有不同的解釋。因此最好在開發前首先將全體的margin、padding設置為0、列表樣式設置為none等。
10.是否忘記了寫DTD?
假如無論怎樣調整不同瀏覽器顯示結果還是不一樣,那麼可以檢查一下頁面開頭是不是忘了寫下面這行DTD:html4.01:
html5:
以上就是小編今天為大家分享的關於Web前端工作中常見的div+css錯誤的檢查和處理方法的注意事項,希望本篇文章能夠對正在從事web前端工作的小夥伴們有所幫助。想要了解更多web前端相關知識記得關注北大青鳥web前端培訓官網。最後祝願小夥伴們面試成功,成為一名優秀的web前端工程師。
Ⅵ 前端js 遇到難以重現的 bug 該怎麼辦
推薦使用Fundebug監控。Fundebug的用戶行為記錄可以幫助你更好地去理解BUG的成因,快速復現bug。
Ⅶ fiddler怎麼定位前端bug還是後端bug
1.發現bug之後,重現bug的時候使用fiddler抓包去分析
2.如果前端提交的數據在fiddler中顯示有誤,那麼就是前端的bug
3.如果在前端提交的數據在fiddler中顯示無誤,那麼就是後台的bug
4.除了fiddler等抓包工具外,還可以通過後台的日誌去判斷