淺入淺出JS中的eval及json
聲明:
首先聲明一下,本人是JS新手,所以不敢說深入,只是把最近對eval的學習經驗拿出來跟大家分享,如果您是高手可略去不看。
適合讀者:
對JS中的eval一知半解,不知eval是如何把字符串轉換為json對象的,在用eval把字符串轉換為json時常遇到“missing ] after element list”錯誤卻不知哪兒錯了的朋友
一、Eval介紹(這部分來自http://www.w3school.com.cn/js/jsref_eval.asp)
定義和用法:eval() 函數可計算某個字符串,并執行其中的的 JavaScript 代碼。
語法:eval(string)
參數string:必需。要計算的字符串,其中含有要計算的 JavaScript 表達式或要執行的語句。
返回值:通過計算 string 得到的值(如果有的話)。
說明:該方法只接受原始字符串作為參數,如果 string 參數不是原始字符串,那么該方法將不作任何改變地返回。因此請不要為 eval() 函數傳遞 String 對象來作為參數。如果試圖覆蓋 eval 屬性或把 eval() 方法賦予另一個屬性,并通過該屬性調用它,則 ECMAScript 實現允許拋出一個 EvalError 異常。
異常:如果參數中沒有合法的表達式和語句,則拋出 SyntaxError 異常。如果非法調用 eval(),則拋出 EvalError 異常。如果傳遞給 eval() 的 Javascript 代碼生成了一個異常,eval() 將把該異常傳遞給調用者。
二、Eval用法示例
對于編程方面的問題我一直認為說明問題最好的方法就是示例,看了上面的定義我們再來看幾個例子:
code 1:
1 var code1="\"a\" + 2";
2 var code2= {"a":2};
3 var code3 ="{\"b\":3}";
4
5 console.log(code1);
6 console.log(eval(code1));
7
8 console.log(code2);
9 console.log(code2.a);
10 console.log(eval(code2));
11 console.log(eval('('+ code2 +')'));
12
13 console.log(code3);
14 console.log(code3.b);
15 t = eval('('+code3+')');
16 console.log(t);
17 console.log(t.b);
從5到17行分別會輸出什么呢?在這里簡單解析一下:
code1是一個字符串加數字的表達式字符串,所以第5行原樣輸出為"a"+2,第6行經eval運算后輸出a2。
code2是一個json對象(關于json定義參考:深入淺出JSON),所以第8行輸出Object { a=2},如果用alert(code2)會彈出[object Object]。第9行輸出2。第10行呢,由于code2是一個json對象,不是一個字符串,因此eval在這里沒有起作用,原樣返回,所以跟第8行輸出一樣。第11行呢,由于code2已經是一個json對象,把json對象兩邊加一個括號進行運算的結果是什么呢,JS中這個語法是錯的,所以這行會報異常,如果我們捕獲一下異常輸出會是什么呢,就是新手非常頭痛的“missing ] after element list”了。
code3是一個json格式的字符串,因此第13行輸出{"b":3}。第14行輸出undefined。第15行對這個字符串加括號(加括號的原因請看下文)后進行eval運算,把字符串轉換成了json對象,所以第16行輸出Object { b=3},第17行輸出3。
是不是這樣呢,看看結果吧:

三、Eval把json格式字符串轉換為json對象為什么要加括號
這一點園子里有一篇文章講得比較清楚(原文鏈接:eval和JSON),這里就不獻丑了,這里直接用原文的話來說明。加上圓括號的目的是迫使eval函數在評估JavaScript代碼的時候強制將括號內的表達式(expression)轉化為對象,而不是作為語句(statement)來執行。舉一個例子,例如對象字面量{},如若不加外層的括號,那么eval會將大括號識別為JavaScript代碼塊的開始和結束標記,那么{}將會被認為是執行了一句空語句。所以下面兩個執行結果是不同的:
code 2:
1 alert(eval("{}"); // return undefined
2 alert(eval("({})");// return object[Object]
所以,code 1中第15行要加上括號,如果不加會怎么樣呢,大家可以測試一下。關于這一點,大家可以類比一下SQL語句,當一個子查詢結果要做為關聯表用時,會在查詢語句兩邊加上括號,如:
code 3:
selecttop10*from TB where ID notin (selecttop5 ID from TB)
四、jquery中ajax返回值的處理
用eval把字符串轉換為json對象用的最多的地方就是在ajax中。ajax的返回值有些是json格式的字符串,所以要用eval('('+返回的json格式字符串+')')來轉換,這樣寫一般是沒有問題的,但現在有很多是用jquery中的ajax方法來做的,jquery的強大也讓很多人在用時容易忽略一些問題,比較常見的就是contentType跟dataType,contentType與本文沒什么關系,這里只說說dataType參數。
dataType可用的類型有xml,html,script,json,jsonp,text,用的比較多的是xml,json,text。有些朋友在用時不管dataType是什么類型,都把返回值eval一下,有時碰巧對了,有時錯了就不知道問題出在哪兒,一籌莫展。
dataType是預期服務器返回的數據類型,如果不指定jQuery將自動根據HTTP包MIME信息返回responseXML或responseText。也就是說如果你dataType寫的是json格式,jQuery在返回時已經把返回值轉換成了json對象,這時就不需要再用eval轉換了,如果dataType寫的是text才需要用eval轉換。
希望本文對新手有所幫助,讓大家不再害怕eval跟json。歡迎留言討論。

浙公網安備 33010602011771號