javascript中eval()函数使用方法
本教程主要重介紹eval()函數的語法與使用方法,及在后面我還補充了eval()解析json數據的相關例子,希望文章能幫助到各位深入理解eval()使用方法吧。
前幾天說到js中盡量不要使用eval,但是eval到底是什么那?今天我們就說說eval的那點事。
首先看一下本定義:
定義和用法
eval() 函數可計算某個字符串,并執行其中的的 JavaScript 代碼。
語法
eval(string)
參數
描述
string 必需。要計算的字符串,其中含有要計算的 JavaScript 表達式或要執行的語句。
返回值
通過計算 string 得到的值(如果有的話)。
說明
該方法只接受原始字符串作為參數,如果 string 參數不是原始字符串,那么該方法將不作任何改變地返回。因此請不要為 eval() 函數傳遞 String 對象來作為參數。
如果試圖覆蓋 eval 屬性或把 eval() 方法賦予另一個屬性,并通過該屬性調用它,則 ECMAScript 實現允許拋出一個 EvalError 異常。
拋出
如果參數中沒有合法的表達式和語句,則拋出 SyntaxError 異常。
如果非法調用 eval(),則拋出 EvalError 異常。
如果傳遞給 eval() 的 Javascript代碼生成了一個異常,eval() 將把該異常傳遞給調用者。
提示和注釋
提示:雖然 eval() 的功能非常強大,但在實際使用中用到它的情況并不多。
實例代碼:
eval函數接收一個參數s,如果s不是字符串,則直接返回s。否則執行s語句。如果s語句執行結果是一個值,則返回此值,否則返回undefined。
需要特別注意的是對象聲明語法“{}”并不能返回一個值,需要用括號括起來才會返回值,簡單示例如下:
| 代碼如下 | 復制代碼 |
| var code1='"a" + 2'; //表達式 varcode2='{a:2}'; //語句 alert(eval(code1)); //->'a2' alert(eval(code2)); //->undefined alert(eval('(' + code2 + ')')); //->[object Object] |
|
eval函數的特點,它總是在調用它的上下文變量空間(也稱為:包,closure)內執行,無論是變量定義還是函數定義都是如此
eval作用域
先看這段代碼:
| 代碼如下 | 復制代碼 |
| var x = 1; (function () { eval('var x = 123;'); })(); console.log(x); |
|
這個代碼得到的是 1 而不是 123
如果想讓 eval 執行的代碼是全局的,那么有幾種方法。
| 代碼如下 | 復制代碼 |
| var x = 1; (function () { window.eval('var x = 123;'); })(); console.log(x); |
|
這個方法標準瀏覽器都可以得到 123 而IE6-8則依然是 1
相同的例如
| 代碼如下 | 復制代碼 |
|
var arr = [0,0,0,0,0,0]; |
|
0,1 貌似不支持IE8- 2,3 貌似不支持 IE7-
反正歸根結底就是兼容性有問題。
不過還在IE下有個 execScript 非常好使。
| 代碼如下 | 復制代碼 |
|
var x = 1; |
|
eval不可能在全局空間內執行,這就給開發帶來了不少問題,也看到過很多人為此郁悶。
不過現在偶終于找到了解決辦法,嘿嘿,可以同時兼容IE和Firefox,方法如下:
| 代碼如下 | 復制代碼 |
| var X2={} //my namespace:) X2.Eval=function(code){ if(!!(window.attachEvent && !window.opera)){ //ie execScript(code); }else{ //not ie window.eval(code); } } |
|
現在如果要想在函數內定義全局代碼,就可以通過調用X2.eval_r(code)方法。
| 代碼如下 | 復制代碼 |
|
var s='global'; |
|
eval解析json
代碼如下:
| 代碼如下 | 復制代碼 |
| var data=" { root: [ {name:'1',value:'0'}, {name:'6101',value:'北京市'}, {name:'6102',value:'天津市'}, {name:'6103',value:'上海市'}, {name:'6104',value:'重慶市'}, {name:'6105',value:'渭南市'}, {name:'6106',value:'延安市'}, {name:'6107',value:'漢中市'}, {name:'6108',value:'榆林市'}, {name:'6109',value:'安康市'}, {name:'6110',value:'商洛市'} ] }"; |
|
這里以jquery異步獲取的數據類型——json對象和字符串為依據,分別介紹兩種方式獲取到的結果處理方式。
1.對于服務器返回的JSON字符串,如果jquery異步請求沒做類型說明,或者以字符串方式接受,那么需要做一次對象化處理,方式不是太麻煩,就是將該字符串放于eval()中執行一次。這種方式也適合以普通javascipt方式獲取json對象,以下舉例說明:
var dataObj=eval("("+data+")");//轉換為json對象
為什么要 eval這里要添加 “("("+data+")");//”呢?
原因在于:eval本身的問題。 由于json是以”{}”的方式來開始以及結束的,在JS中,它會被當成一個語句塊來處理,所以必須強制性的將它轉換成一種表達式。
加上圓括號的目的是迫使eval函數在處理JavaScript代碼的時候強制將 括號內的表達式(expression)轉化為對象,而不是作為語 句(statement)來執行。舉一個例子,例如對象字面量{},如若不加外層的括號,那么eval會將大括號識別為JavaScript代碼塊的開始 和結束標記,那么{}將會被認為是執行了一句空語句。所以下面兩個執行結果是不同的:
代碼如下:
| 代碼如下 | 復制代碼 |
| alert(eval("{}"); // return undefined alert(eval("({})");// return object[Object] |
|
對于這種寫法,在JS中,可以到處看到。
如: (function()) {}(); 做閉包操作時等。
代碼如下:
| 代碼如下 | 復制代碼 |
| alert(dataObj.root.length);//輸出root的子對象數量 $.each(dataObj.root,fucntion(idx,item){ if(idx==0){ return true; } //輸出每個root子對象的名稱和值 alert("name:"+item.name+",value:"+item.value); }) |
|
注:對于一般的js生成json對象,只需要將$.each()方法替換為for語句即可,其他不變。
2.對于服務器返回的JSON字符串,如果jquery異步請求將 type(一般為這個配置屬性)設為“json”,或者利 用$.getJSON()方法獲得服務器返回,那么就不需要eval()方法了,因為這時候得到的結果已經是json對象了,只需直接調用該對象即可,這 里以$.getJSON方法為例說明數據處理方法:
代碼如下:
| 代碼如下 | 復制代碼 |
| $.getJSON("http://www.111cn.net/",{param:"gaoyusi"},function(data){ //此處返回的data已經是json對象 //以下其他操作同第一種情況 $.each(data.root,function(idx,item){ if(idx==0){ return true;//同countinue,返回false同break } alert("name:"+item.name+",value:"+item.value); }); }); |
|
這里特別需要注意的是方式1中的eval()方法是動態執行其中字符串(可能是js腳本)的,這樣很容易會造成系統的安全問題。所以可以采用一些規避了eval()的第三方客戶端腳本庫,比如JSON in JavaScript就提供了一個不超過3k的腳本庫。
*eval執行的常見錯誤
---源碼
| 代碼如下 | 復制代碼 |
|
console.log("Eval Usage"); var str2_err = "{name: 'dzh'}"; ---結果 Eval Usage |
|
---分析原因
1)str1_err說明了定義匿名函數導致的報錯; 遇到空的'()', 會報錯;
2)str2_err說明了對于'{}',引擎解析時會把括號理解為代碼塊, 而程序原意是一個對象直接量; 所以常用的方式是在'{}'外圍加小括號, 那么eval就先執行求值運算, 它就返回對象.
綜述, 使用eval時, 要考慮引擎是如何理解傳入的字符串代碼.
出處:http://www.111cn.net/wy/js-ajax/64587.htm
總結
以上是生活随笔為你收集整理的javascript中eval()函数使用方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大华、海康、宇视、华为等厂家RTSP标准
- 下一篇: 技术分享:杂谈如何绕过WAF(Web应用