一、錯誤處理的重要性
以前,javascript總是因為會出現奇怪的令人困惑的錯誤訊息而知名,調試這種資訊確實是一種痛苦的經曆。
因此,第四版的瀏覽器(IE4.0和Netscape4.0)包含了一些基本的錯誤處理功能。不久之後,ECMA和ECMASCript第三版中提出新的解決方案。
最新的ECMAScript添加了異常處理機制,採用了從Java中移植過來的模型,第三版用ECMAScript第二版中的一些保留字實現了try…catch..finally結構以及throw操作符
1.1、早期瀏覽器的錯誤處理
早期的瀏覽器(如IE3.0)沒有錯誤處理。函數通過返回一個無效值(一般是null、false或-1,根據不同的函數不同)來表示發生了錯誤,考慮以下代碼:
var index = findColor(colorarray,”red”);
If (index==-1)
alert(“該項不存在”);
else
alert(“該項的位置是:”+index);
以上的問題在於函數findcolor的傳回值-1無從判斷是沒有找到還是出錯了。
錯誤和錯誤處理將協助我們解決這個問題
在javascript引入錯誤處理後,web開發人員就可以更好的對代碼進行控制了。好的錯誤處理技術可以讓指令碼的開發、測試和部署更流暢。Js尤為如此,因為它缺乏標準的開發環境來指導開發人員。
二、錯誤和異常
錯誤的類型無外兩種:語法錯誤和執行階段錯誤
1、語法錯誤
傳統程式設計語言編譯時間解析錯誤,在javascript中發生在解釋時。這些錯誤是由代碼中的意外字元直接造成的。然後就不能完全編譯/解釋了,如:
window.alert(“test”
不過,在javascript中,只有在同一線程中的代碼會受到錯誤碼的影響。在其他線程中的代碼和其他外部參考的檔案中的代碼,如果不依賴於包含錯誤的代碼,則可以繼續執行
如:
<head>
<script type=“text/javascript”>
function handlerLoad() {
windows.open(“about:blank”);
}
function handleClick(){
alert(“click”);
}
</script>
</head>
<body onload =“handlerLoad()”>
<input type=“button” value=“test” onclick=“handlerClick()”/>
</body>
這段JS代碼,頁面載入時會報JS錯誤,但不會影響handleClick的執行
三、處理錯誤
Javascript提供了兩種特殊的錯誤處理方式
BOM包含一個onerror事件處理函數,這個window對象與映像對象上都有
同時ECMAScript定義了另一個從java中借鑒過來的try…catch結構來處理異常
1. onerror事件處理函數
<SCRIPT LANGUAGE="JavaScript">
<!--
function handleError(){
alert("出錯了");
return true;}
window.onerror = handleError; //屏蔽所有的錯誤提示,很危險
//-->
</SCRIPT>
</HEAD>
<BODY onload="handleLoad()">
</BODY>
</HTML>
這樣,網頁出錯,便會彈出”出錯了“訊息框”,但不幸的是網頁仍會彈出錯誤提示框
如果想去掉這個提示框,改造如下:
} function handleError()
} {
} alert("出錯了");
} return true;
} }
2. 取出錯誤資訊
onerror事件處理函數提供了三種資訊來確定錯誤確切的性質
> 錯誤資訊—對於給定錯誤,瀏覽器會顯示同樣的資訊
> URL – 在哪個檔案中發生了錯誤
> 行號 – 給定URL中發生的錯誤的行號
如:<SCRIPT LANGUAGE="JavaScript">
<!--
function handleError(sMessage,sURL,sLine) {
alert(“出錯了.\n”+“訊息:"+sMessage+"\nURL:"+sURL+
"\n出錯行號:"+sLine);
return true; }
window.onerror = handleError;
//-->
</SCRIPT>
//定製我們的錯誤提示
映像載入錯誤
<img src=“blue.gif” onerror=“alert(‘載入映像出錯’)”/>
和window.onerror不同,img的onerror事件處理函數無任何額外訊息的參數.
圖片沒正常載入就會觸發onerror事件
使用onerror事件處理函數的主要問題是,它是BOM的一部分,所以,沒有任何的標準能控制它們的行為。因此任何的瀏覽器使用這個事件處理函數處理錯誤的方式也明顯不同。
如:IE中發生error事件時,正常的代碼會繼續執行;所有的變數和資料會保留下來,並可通過onerror事件處理函數訪問。然而在mozilla中,正常的代碼執行都會結束,同時所有錯誤處理之前的變數和資料都會被銷毀。
還有其瀏覽器根本不支援window對象上的onerror事件處理函數,但它們都支援映像上的onerror事件
try…catch語句
ECMAScript第三版支援try…catch…finally文法
基本文法:
try{
//code
}catch([exception]){
//code
}[finally{
//code
}]
如:<SCRIPT LANGUAGE="JavaScript">
<!--
try{
alert("ok");
}catch(exception){
alert("an error processed");
}finally{
alert("finally");
}
alert("ok");
//-->
</SCRIPT>
注意:與java語言不同的是:不支援多重catch語句,但支援嵌套catch語句
如:try{ var a = document.getElementById("txtUser");
alert(a.value);
}catch(ex) {
alert(“Error”);
}
再如: 彈出詳細錯誤資訊try{ var a = document.getElementById("txtUser");
alert(a.value);
}catch(ex) {
alert(ex.message); //error
}
try{ var a = document.getElementById("txtUser");
alert(a.value);
}catch(ex)
{try{
alert(oException.message);}
catch (ex){
alert(ex.message); } }
四、 Error對象
類似於java的錯誤基類Exception,javascript有個基類Error,Error對象有以下特徵:
p name –表示錯誤類型的字串
p message – 實際的錯誤資訊
Error對象的名稱對應於它的類,可以是以下值之一
1、EvalError: 錯誤發生在eval()函數中
2、RangeError:數位值超過javascript可表示的範圍
3、ReferenceError: 使用了非法的引用
4、SyntaxError: 在eval()函數調用中發生了語法錯誤。
5、TypeError:變數的類型不是預期所需的
6、URIError: 在encodeURI()或者decodeURI()函數中發生的錯誤
說明:Mozzilla和IE均擴充了Error對象,如IE中提供了一個number特性來表示錯誤代號,也可用description代替message
錯誤類型判斷 二種方法:
方法1:通過name屬性判斷
方法2: 通過instanceof操作符
如:try{ var scriptStr =" var a=0;var b=1;var c=a++b;alert(c)";
eval(scriptStr);
}catch(ex)
{ if (ex instanceof SyntaxError)
{ alert("文法出錯了"); } }
拋出異常
ECMASCript還引入throw語句,用於有目的的拋出異常
文法如下:throw error_object
error_object可以是字串、數字、布爾值或是實際的對象。如:
throw “an error occurred”;
throw 5007;throw true;
throw new Object();
throw new Error();
throw new Error(“error”);
throw new Error(10001,”error”);
最佳化javascript
javascript是作為原始碼下載,然後瀏覽器對其進行 解釋的(不存在編譯問題),因此javascript的效能就體現在速度方法,而速度又被分割成兩部分:下載時間和執行速度
1、 下載時間: 使用java等其他語言我們可以不必考慮100個字元長的變數名及大量的注釋.因為這些在編譯後名稱會被替換掉,注釋也會被自動刪除,但javascript開發人員,就沒有這麼爽了!
增加下載時間的關鍵因素是指令碼所包含的位元組數.
記住一個關鍵數字1160;這是能放入單個TCP-IP包中的位元組數。最好能將每個javascript檔案都保持在1160位元組以下以擷取最優的下載時間
減小代碼下載的時間方法:
ü 刪除注釋
ü 刪除定位字元和空格
ü 刪除所有的換行
ü 替換變數名
如:function dosomthing(sname,sage,scity)
=> function dosomthing(a,b,c)
推薦一個工具:ECMASCript Cruncher
:http://www.saltstorm.net/depo/esc/
如:C:\>cscript C:\ESC-1.14\ESC.wsf -l [0-4] -ow outputfile.js inputfile1.js [inputfile2.js]
說明:
cscript是windows shell指令碼解釋程式。
[0-4]是一個壓縮等級
-ow 表示下一個參數是最佳化後輸出的檔案名稱,最後剩下的是要最佳化的js檔案
ESC支援以下四個最佳化等級
等級 |
描述 |
0 |
不改變指令碼,將多個檔案合并到單個檔案 |
1 |
刪除所有注釋 |
2 |
除等級1個,再刪除額外的定位字元和空格 |
3 |
除等級2外,再刪除換行 |
4 |
除等級3個,再進行變數名替換 |
|
|
其他減少位元組數的方法
ü 替換布爾值
相對於比較來說:true等於1,false等於0.因此指令碼包含的字面量true都可以用1來替換,而false可以用0替換
如:var bFound=false;
for(var i=0;i<aTest.length && !bFound;i++)
{
bFound = true;
}
可以替換成:
var bFound =0;
for(var i=0;i<aTest.length && !bFound;i++)
{
bFound = 1;
}
縮短否定檢測
如:
if (oTest!=undefined){}
if (oTest != null){}
Þ if (oTest!=false){} if (!oTest){ //do something}
ü 使用數組和對象字面量
var aTest = new Array(); => var aTest = [ ]; //相當於建立一個空數組
var oTest = new Object();
Þ oTest = {};
如:
var oCar = new Object();
oCar.color = “red”;
oCar.name=“mycar”;
=>
var oCar = {color:”red”,name:”mycar”}
} 執行時間
1、關注範圍
ü 使用局部變數
如果直接使用變數而不事先使用var進行聲明,變數就會建立在window範圍內,解釋程式就會搜尋整個範圍樹
如:<SCRIPT LANGUAGE="JavaScript">
<!--
function mytest()
{
svar = "Micro";
alert(svar);
}
mytest();
alert("ok"+svar);
//-->
</SCRIPT>
} 避免with語句
範圍越少,速度越快,這是不使用with語句的原因
如:alert(document.title);
alert(document.body.tagName);
alert(document..location);
替換成:with(document)
{
alert(title);
alert(body.tagName);
alert(location);
}
最好避免使用with語句,減少的代碼長度並不能彌補損失的效能
} 電腦科學基礎
ü 選擇正確的演算法
1、反轉迴圈.速度要塊
for(var i=0;i<aValues.length;i++)
{ }
=>
for(var i=aValues.length;i>=0;i--)
{ }
} 翻轉迴圈
如:var i=0;
while(i<aValues.length)
{
i++;
}
=>:do{
i++
} while(i>=0)
Þ var i=aValues.length-1;
do{
i--;
}while(i>=0)
u 其他
ü 避免字串連結,通過自己的封裝的方法
ü 優先使用內建方法
ü 儲存常用的值
ü 節約使用DOM
(轉自:http://www.cnblogs.com/aqbyygyyga/archive/2011/10/29/2228824.html)