讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議14:不要濫用eval >

建議14:不要濫用eval

eval是一個被濫用得很嚴重的JavaScript特性。eval函數傳遞一個字符串給JavaScript編譯器,該字符串會被當成一段JavaScript程序來解析和執行。

很多開發者對JavaScript語言一知半解,卻喜歡使用eval。例如,如果只知道點表示法,卻不知道下標表示法,就會按如下方法編寫代碼:


eval("value=obj."+key+";");


而不是按如下方法編寫:


value=obj[key];


使用eval形式的代碼會更加難以閱讀。這種形式將使代碼性能顯著降低,因為eval必須運行編譯器,同時這種形式減弱了Web應用的安全性,因為它向被求值的文本授予了太多的權限。使用eval與使用with語句一樣,降低了語言的性能。

除了顯式調用eval外,JavaScript還支持隱式調用eval。Function構造器是eval的另一種形式,所以也應該避免使用它。當傳遞的是字符串參數時,setTimeout和setInterval函數(瀏覽器提供的函數,能接受字符串參數或函數參數)會像eval那樣去處理,因此也應該避免使用字符串參數形式。例如,下面是使用函數參數形式進行的處理。


var obj={

show1:function{

alert("時間到!");

},

show2:function{

alert("10秒一次的提醒!");

};

};

setTimeout(obj.show1,1000);

setTimeout("obj.show1;",2000);

setInterval(obj.show2,10000);

setInterval("obj.show2;",10000);


在Ajax應用中,JSON是一種流行的瀏覽器端與服務器端之間傳輸數據的格式。服務器端傳過來的數據在瀏覽器端通過JavaScript的eval方法轉換成可以直接使用的對象。然而,在瀏覽器端執行任意的JavaScript會帶來潛在的安全風險,惡意的JavaScript代碼可能會破壞應用。對於這個問題,有兩種解決方法:

❑帶註釋的JSON(JSON comments filtering)。

❑帶前綴的JSON(JSON prefixing)。

這兩種方法都是在Dojo中用來避免JSON劫持(JSON hijacking)的方法。帶註釋的JSON指的是從服務器端返回的JSON數據都是帶有註釋的,瀏覽器端的JavaScript代碼需要先去掉註釋的標記,再通過eval來獲得JSON數據。這種方法一度被廣泛使用,後來被證明並不安全,還會引入其他的安全漏洞。帶前綴的JSON是目前推薦使用的方法,這種方法的使用非常簡單,只需要在從服務器端返回的JSON字符串之前加上{}&&,再調用eval方法。關於這兩種方法的細節,可參考http://www.ibm.com/developerworks/cn/web/wa-lo-dojoajax1/?S_TACT=105AGX52&S_CMP=tec-csdn#resources中的內容。對JSON字符串進行語法檢查,安全的JSON應該是不包含賦值和方法調用的。在JSON的RFC 4627中,給出了判斷JSON字符串是否安全的方法,此方法通過兩個正則表達式來實現(代碼如下)。


var my_JSON_object=!(/[^,:{}\[\]0-9.\-+Eaeflnr-u\n\r\t]/.test(text.replace(/"(\\.|[^"\\])*"/g,'')))&&eval('('+text+')');